Ribbon實現客戶端的負載均衡。那什麼是客戶端負載均衡呢?這裏貼一個講解客戶端負載均衡和服務端負載均衡的連接。算法
分別是IRule、IPing、ServerList 、ServerListFilter、ServerListUpdater、ILoadBalancer緩存
定義軟件負載平衡器操做的接口。動態更新一組服務列表及根據指定算法從現有服務器列表中選擇一個服務。bash
DynamicServerListLoadBalancer組合Rule、IPing、ServerList、ServerListFilter、ServerListUpdater 實現類,實現動態更新和過濾更新服務列表服務器
這是DynamicServerListLoadBalancer的子類,主要加入zone的因素。統計每一個zone的平均請求的狀況,保證從全部zone選取對當前客戶端服務最好的服務組列表app
存儲服務列表。分爲靜態和動態。若是是動態的,後臺有個線程會定時刷新和過濾服務列表負載均衡
根據特定算法中從服務列表中選取一個要訪問的服務ui
一共有7種負載均衡策略:google
users:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.WeightedResponseTimeRule
複製代碼
在後臺運行的一個組件,用於檢查服務列表是否存活url
這裏也有不一樣的策略,分別有如下策略:spa
不執行真正的ping。若是Discovery Client認爲是在線,則程序認爲本次心跳成功,服務活着
此組件會使用HttpClient調用服務的一個URL,若是調用成功,則認爲本次心跳成功,表示此服務活着
永遠返回true,即認爲服務永遠活着
默認實現,默認返回true,即認爲服務永遠活着
經常使用的規則有如下幾種:
從配置文件中獲取全部服務列表,配置舉例:
sample-client:
ribbon.listOfServers: www.microsoft.com:80,www.yahoo.com:80,www.google.com:80
複製代碼
從Eureka Client中獲取服務列表
代理類,根據 ServerList 的值實現具體的邏輯
該接口容許過濾配置或動態獲取的具備所需特性的服務器列表。ServerListFilter 是 DynamicServerListLoadBalancer 用於過濾從 ServerList 實現返回的服務器的組件。
經常使用 ServerListFilter 實現有如下幾種:
過濾掉全部的不和客戶端在相同zone的服務,若是和客戶端相同的zone不存在,纔不過濾不一樣zone有服務。
ZoneAffinityServerListFilter的子類。和ZoneAffinityServerListFilter類似,可是比較的zone是發佈環境裏面的zone。過濾掉全部和客戶端環境裏的配置的zone的不一樣的服務,若是和客戶端相同的zone不存在,纔不進行過濾。
ZoneAffinityServerListFilter的子類。此過濾器確保客戶端僅看到由ServerList實現返回的整個服務器的固定子集。 它還能夠按期用新服務器替代可用性差的子集中的服務器。
被DynamicServerListLoadBalancer用於動態的更新服務列表。
默認的實現策略。此對象會啓動一個定時線程池,定時執行更新策略
當收到緩存刷新的通知,會更新服務列表。
定義各類配置信息,用來初始化ribbon客戶端和負載均衡器
經常使用IClientConfig實現有如下幾種:
IClientConfig的默認實現,配置文件裏的部分值爲ribbon
@RestController
@RequestMapping("order")
public class OrderController {
@Autowired
private LoadBalancerClient loadBalancerClient;
@Autowired
private RestTemplate restTemplate;
/**
* RestTemplate的第一種用法,寫死調用連接
* @return
*/
@GetMapping("testOrder")
public String testOrder() {
RestTemplate restTemplate = new RestTemplate();
String forObject = restTemplate.getForObject("http://localhost:9000/product/test", String.class);
return forObject;
}
/**
* 利用LoadBalancerClient獲取應用的url
* @return
*/
@GetMapping("testOrder2")
public String testOrder2() {
RestTemplate restTemplate = new RestTemplate();
ServiceInstance prodtct = loadBalancerClient.choose("product"); //product是調用服務名
String url = String.format("http://%s:%s/product/test", prodtct.getHost(), prodtct.getPort());
String s = restTemplate.getForObject(url, String.class);
return s;
}
/**
* 利用@LoadBalanced註解,restTemplate中直接使用應用名字。這裏須要配置RestTemplateConfig
* @return
*/
@GetMapping("testOrder3")
public String testOrder3() {
String s = restTemplate.getForObject("http://product/product/test", String.class); //product是調用服務名
return s;
}
}
複製代碼
RestTemplateConfig 配置文件
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
複製代碼
protected Server getServer(String serviceId) {
return getServer(getLoadBalancer(serviceId)); // 經過 getLoadBalancer 方法拿到 server list。
// 在這裏 getLoadBalancer 其實返回的是一個 LoadBalancer 這個 LoadBalancer 中包含 ServerList、IRule、IPing 等各類所須要的信息。
}
protected Server getServer(ILoadBalancer loadBalancer) {
if (loadBalancer == null) {
return null;
}
// 經過 IRule 負載均衡策略
return loadBalancer.chooseServer("default"); // TODO: better handling of key
}
複製代碼
Ribbon 客戶端負載均衡實現主要是先經過算法策略拿到 server list 以後再經過 IRule 負載算法去選取一個合適的 server 提供服務。