一、客户端负载均衡器 Ribbon
客户端向服务器如Eureka Server拉取已经注册的服务信息,然后根据负载均衡策略,
直接命中哪一台服务器发送请求。 整个过程在客户端完成,不需要服务器的参与。
Spring Cloud客户端的负载均衡就是Ribbon组件。
包括
1、RestTemplate
2、Feign
3、Zuul
二、Ribbon实现负载均衡的核心有三点
服务发现: 发现依赖服务的列表,就是依据服务的名字,把该服务所有的实例都找出来。
服务选择规则: 依据规则策略,从多个服务中选择一个有效的服务。
服务监听:检查失效的服务,做到高效剔除。
三、Ribbon固定serverList实践
1、从配置文件里配置固定的要访问的服务列表
larry-client.ribbon.MaxAutoRetries=1 larry-client.ribbon.MaxAutoRetriesNextServer=1 larry-client.ribbon.OkToRetryOnAllOperations=true larry-client.ribbon.ServerListRefreshInterval=2000 larry-client.ribbon.ConnectTimeout=3000 larry-client.ribbon.ReadTimeout=3000 larry-client.ribbon.listOfServers = http://www.baidu.com,http://www.jd.com
listOfServers 分别为百度和JD
2、测试类
public class App
{
public static void main(String[] args) throws IOException, URISyntaxException, ClientException {
//读取配置文件
ConfigurationManager.loadPropertiesFromResources("ribbon.properties");
System.out.println(ConfigurationManager.getConfigInstance().getProperty("larry-client.ribbon.listOfServers"));
//构建一个HttpClient
RestClient client = (RestClient) ClientFactory.getNamedClient("larry-client");
HttpRequest request = HttpRequest.newBuilder().uri(new URI("/")).build();
for(int i = 0; i < 5; i++){
HttpResponse response = client.executeWithLoadBalancer(request);
System.out.println("Status code for " + response.getRequestedURI() +" : " + response.getStatus());
}
}
}
3、输出结果如下

访问baidu和jd,是轮询调用。
四、Ribbon的主要组件
1、ServerList:
2、IRule
3、ServerListFilter
流程: 通过ServerList获得所有可用的服务列表,通过ServerListFilter顾虑一部分地址,最后在剩下的地址中,通过IRule选择一个实例作为最终目标结果
IRule
通过特定算法选取要访问的服务。
IRule常使用BestAvailableRule和WeightedResponseTimeRule

RandomRule 随机规则的源码如下
public class RandomRule extends AbstractLoadBalancerRule {
public RandomRule() {
}
@SuppressWarnings({"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"})
public Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
} else {
Server server = null;
while(server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers();
List<Server> allList = lb.getAllServers();
int serverCount = allList.size();
if (serverCount == 0) {
return null;
}
int index = this.chooseRandomInt(serverCount);
server = (Server)upList.get(index);
if (server == null) {
Thread.yield();
} else {
if (server.isAlive()) {
return server;
}
server = null;
Thread.yield();
}
}
return server;
}
}
protected int chooseRandomInt(int serverCount) {
return ThreadLocalRandom.current().nextInt(serverCount);
}
public Server choose(Object key) {
return this.choose(this.getLoadBalancer(), key);
}
public void initWithNiwsConfig(IClientConfig clientConfig) {
}
}
获得所有在线的服务 List<Server> upList = lb.getReachableServers();
获得所有的服务 List<Server> allList = lb.getAllServers();
然后通过chooseRandomInt这个方法随机选择一个服务。
五、 IPing:探测服务存活状态,
1、IPing是Ribbon保证服务可用的基石,常见实现:NIWSDiscoveryPing,PingUrl)

2、IPing实践: NIWSDiccoveryPing依赖于Eureka
