一、客户端负载均衡器 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