一、本地負載均衡和Nginx負載均衡的區別
1、本地負載均衡
消費者服務從我們的註冊中心獲取到集羣地址列表,緩存到JVM本地,本地採用負載均衡策略,實現RPC的遠程調用。之所以叫本地感覺是相對的,消費者基於生產者就好比是客戶端和服務端之間的關係,所以這也叫本地負載均衡吧。
2、Nginx負載均衡
客戶端的所有請求都會交給Nginx代理,轉發到相應的服務器上,這個是服務器端的負載均衡。
二、ribbon中的負載均衡規則
1、ribbon中IRule的實現類圖解
2、各個類的作用
策略類型 | 策略說明 |
---|---|
RoundRobinRule | 輪循。相當於就是將訪問次數和集羣數(從註冊中心獲取到指定爲服務名的集羣地址列表的數量)進行取模計算出index,根據index取到相應的server |
RandomRule | 隨機。在index上隨機,選擇index對應位置的server |
RetryRule | 選定的負載均衡策略機上重試機制。 |
BestAvailableRule | 會先過濾掉由於多次訪問故障而處於斷路器跳閘狀態的服務,然後選擇一個併發量最小的服務 |
AvailabilityFilteringRule | 先過濾掉故障實例,再選擇併發較小的實例 |
ZoneAvoidanceRule | 默認策略。複合判斷server所在區域的性能和server的可用性選擇server,如果微服務沒設置zone,底層採用的還是輪循 |
WeightedResponseTimeRule | 響應速度越快的實例選擇權重越大,越容易被選擇 |
3、配合nacos實現自定義權重的負載均衡策略
相當於是每個註冊的微服務都對應這麼一個配置類。
成員變量中有這麼一個:private static NamingService namingService;
,接口中有這麼一個使用給定負載均衡算法的方法。
/**
* Select one healthy instance of service using predefined load balance strategy
*
* @param serviceName name of service
* @return qualified instance
* @throws NacosException
*/
Instance selectOneHealthyInstance(String serviceName) throws NacosException;
AbstractLoadBalancerRule已經幫我們實現了IRule接口中的一些方法,直接繼承來得簡單方便。
public class NacosWeightRule extends AbstractLoadBalancerRule {
@Autowired
private NacosDiscoveryProperties nacosDiscoveryProperties;
@Override
public void initWithNiwsConfig(IClientConfig iClientConfig) {
//一般都是爲空
}
@Override
public Server choose(Object o) {
BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
String name = loadBalancer.getName(); //獲取到想要請求的微服務名稱
NamingService namingService = nacosDiscoveryProperties.namingServiceInstance(); //拿到服務發現的API
Instance instance = null;
try {
instance = namingService.selectOneHealthyInstance(name); //自帶權重的負載均衡算法
} catch (NacosException e) {
e.printStackTrace();
return null;
}
return new NacosServer(instance);
}
}
將權重的負載均衡策略配置成全局。
@Configuration
public class RibbonConfiguration {
@Bean
public IRule nacosClusterRule() {
return new NacosClusterWeightRule();
}
}
啓動類加上@RibbonClients(defaultConfiguration = RibbonConfiguration.class)
。
基於集羣優先調用的權重負載均衡算法也同理,相當於再增加一步對集羣名進行過濾並放入新的集合中。再判斷一下新集合是否爲空,爲空就直接用上面的API,不爲空也是類似上面的操作。
三、測試