Ribbon 提供了几个负载均衡的组件,其目的就是让请求转给合适的服务器处理,因此,如何选择合适的服务器变成了负载均衡机制的核心,Ribbon 提供了如下负载均衡规则:
- RoundRobinRule:默认规则,通过简单的轮询服务列表来选择服务器
-
AvailabilityFilteringRule:可用性筛选规则
- 忽略无法连接的服务器,默认情况下,如果3次连接失败,该服务将会被置为"短路"的状态,该状态持续30秒;如果再次连接失败,"短路"状态的持续时间将会以几何级数增加,可以通过 niws.loadbalancer.<clientName>.connectionFailureCountThreshold 属性,来配置连接失败的次数;
- 忽略并发过高的服务器,如果连接到该服务器的并发数过高,也会被这个规则忽略,可以通过修改 <clientName>.ribbon.ActiveConnectionsLimit 属性来设定最高并发数。
- 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());
}
}
}
}