Ribbon 負載均衡機制
Ribbon 提供了幾個負載均衡的組件,其目的就是讓請求轉給合適的服務器處理,因此,如何選擇合適的服務器變成了負載均衡機制的核心,Ribbon 提供了如下負載均衡規則:
- RoundRobinRule:默認規則,通過簡單的輪詢服務列表來選擇服務器
-
AvailabilityFilteringRule:可用性篩選規則
- 忽略無法連接的服務器,默認情況下,如果3次連接失敗,該服務將會被置為"短路"的狀態,該狀態持續30秒;如果再次連接失敗,"短路"狀態的持續時間將會以幾何級數增加,可以通過 niws.loadbalancer.<clientName>.connectionFailureCountThreshold 屬性,來配置連接失敗的次數;
- 忽略並發過高的服務器,如果連接到該服務器的並發數過高,也會被這個規則忽略,可以通過修改 <clientName>.ribbon.ActiveConnectionsLimit 屬性來設定最高並發數。
- 忽略無法連接的服務器,默認情況下,如果3次連接失敗,該服務將會被置為"短路"的狀態,該狀態持續30秒;如果再次連接失敗,"短路"狀態的持續時間將會以幾何級數增加,可以通過 niws.loadbalancer.<clientName>.connectionFailureCountThreshold 屬性,來配置連接失敗的次數;
- WeightedResponseTimeRule:為每個服務器賦予一個權重值,服務器的響應時間越長,該權重值就越少,這個規則會隨機選擇服務器,權重值有可能會決定服務器的選擇
- ZoneAvoidanceRule:該規則以區域、可用服務器為基礎進行服務器選擇,使用區域(Zone)對服務器進行分類
- BestAvailableRule:忽略"短路"的服務器,並選擇並發數較低的服務器
- RandomRule:隨機選擇可用服務器
- RetryRule:含有重試的選擇邏輯,如果使用 RoundRobinRule 選擇的服務器無法連接,那麽將會重新選擇服務器
Ribbon 提供的負載規則基本可以滿足大部分的需求,如果有更為復雜的要求,則可以自定義負載規則,如果需要實現自定義規則,需要實現 com.netflix.loadbalancer.IRule 接口,示例如下:
package org.lixue.ribbon.client;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
import java.util.List;
public class MyRule implements IRule{
private ILoadBalancer loadBalancer;
/**
*選擇服務器
*/
public Server choose(Objectkey){
List<Server>allServers=loadBalancer.getAllServers();
if(allServers.size()>0){
//固定返回最後一個
return allServers.get(allServers.size()-1);
}else
return null;
}
public void setLoadBalancer(ILoadBalancerlb){
this.loadBalancer=lb;
}
public ILoadBalancer getLoadBalancer(){
returnthis.loadBalancer;
}
}
可以直接使用編碼方式來設置負載規則,示例如下:
package org.lixue.ribbon.client;
import com.netflix.client.ClientFactory;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.Server;
public class RibbonClient{
public static void main(String[]args)throws Exception{
ConfigurationManager.loadCascadedPropertiesFromResources("ribbon-client");
ILoadBalancerloadBalancer=ClientFactory.getNamedLoadBalancer("MyRibbonClient");
IRule chooseRule=new MyRule();
chooseRule.setLoadBalancer(loadBalancer);
for(int i=0;i<10;i++){
Server server=chooseRule.choose(null);
System.out.println("request"+server.getHostPort());
}
}
}
也可以使用配置的方式來設置負載規則,配置屬性名 NFLoadBalancerRuleClassName ,配置值為自定義負載規則類的完整名稱(命名空間和類名),修改 src/main/resources 目錄下的 ribbon-client.properties 配置如下:
#配置服務器列表
MyRibbonClient.ribbon.listOfServers=localhost:8080,localhost:8002
#配置負載均衡規則IRule的實現類
MyRibbonClient.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.WeightedResponseTimeRule
#配置負載均衡實現類
MyRibbonClient.ribbon.NFLoadBalancerClassName=com.netflix.loadbalancer.ZoneAwareLoadBalancer
修改代碼如下:
package org.lixue.ribbon.client;
import com.netflix.client.ClientFactory;
import com.netflix.config.ConfigurationManager;
import com.netflix.loadbalancer.*;
public class RibbonClient{
public static void main(String[]args)throwsException{
ConfigurationManager.loadCascadedPropertiesFromResources("ribbon-client");
ILoadBalancerloadBalancer=ClientFactory.getNamedLoadBalancer("MyRibbonClient");
for(inti=0;i<10;i++){
Serverserver=loadBalancer.chooseServer(null);
if(server!=null){
System.out.println("request"+server.getHostPort());
}
}
}
}
Ribbon 負載均衡機制