本文已参与「新人创作礼」活动,一起开启掘金创作之路。
netflix ribbon 负载均衡 - 直联方式
启动服务实例
用8763和8764两个端口号启动两个服务实例。
服务的客户端(基于ribbon)
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-httpclient</artifactId>
</dependency>
// 服务名称是:eureka-provider-ribbon-p2p.ribbon
ConfigurationManager.getConfigInstance().setProperty("eureka-provider-ribbon-p2p.ribbon" + ".listOfServers", "localhost:7073,localhost:7074");
RestClient namedClient =
(RestClient) ClientFactory.getNamedClient("eureka-provider-ribbon-p2p");
for (int i = 0; i < 10; i++) {
try {
namedClient.executeWithLoadBalancer(HttpRequest.newBuilder().uri("/product").build());
} catch (Exception e) {
log.info("nothing");
}
}
10次请求,均匀分布在了两个服务实例上,每个服务实例承载了5次请求。
ILoadBalancer原生接口以及IRule内置的规则
ILoadBalancer原生的负载均衡器接口
默认使用round robin轮询策略,直接从服务器列表里轮询
RestClient底层就是基于默认的BaseLoadBalancer来选择一个server
ILoadBalancer balancer = new BaseLoadBalancer();
List<Server> serverList = Arrays.asList(8080, 8081).stream().map(port -> new Server(
"localhost", port)).collect(Collectors.toList());
balancer.addServers(serverList);
for (int i = 0; i < 10; i++) {
Server server = balancer.chooseServer(null);
log.info("server : {}", server);
}
自定义负载均衡的规则
ILoadBalancer负载均衡器,底层是基于IRule,负载均衡算法,从服务器list中选择一个server出来
负载均衡器是基于一个IRule接口指定的负载均衡规则,来从服务器列表里获取每次要请求的服务器的。
负载均衡的一些底层API主要是ILoadBalancer和IRule。
ILoadBalancer balancer = new BaseLoadBalancer();
List<Server> serverList = Arrays.asList(8080, 8081).stream().map(port -> new Server(
"localhost", port)).collect(Collectors.toList());
balancer.addServers(serverList);
class MyRule implements IRule {
private ILoadBalancer iLoadBalancer;
@Override
public Server choose(Object o) {
List<Server> allServers = iLoadBalancer.getAllServers();
Server server = allServers.get(0);
return server;
}
@Override
public void setLoadBalancer(ILoadBalancer iLoadBalancer) {
this.iLoadBalancer = iLoadBalancer;
}
@Override
public ILoadBalancer getLoadBalancer() {
return iLoadBalancer;
}
}
((BaseLoadBalancer) balancer).setRule(new MyRule());
for (int i = 0; i < 10; i++) {
Server server = balancer.chooseServer(null);
log.info("server : {}", server);
}
IRule 内置的负载均衡规则
RoundRobinRule:系统内置的默认负载均衡规范,直接round robin轮询,从一堆server list中,不断的轮询选择出来一个server,每个server平摊到的这个请求,基本上是平均的
AvailabilityFilteringRule:这个rule就是会考察服务器的可用性
如果3次连接失败,就会等待30秒后再次访问;如果不断失败,那么等待时间会不断边长
如果某个服务器的并发请求太高了,那么会绕过去,不再访问
WeightedResponseTimeRule:带着权重的,每个服务器可以有权重,权重越高优先访问,如果某个服务器响应时间比较长,那么权重就会降低,减少访问
ZoneAvoidanceRule:根据区域和服气来进行负载均衡,说白了,就是机房的意思
BestAvailableRule:忽略那些连接失败的服务器,然后尽量找并发比较低的服务器来请求
RandomRule:随机找一个服务器
RetryRule:可以重试,就是通过round robin找到的服务器请求失败,可以重新找一个服务器
ribbon主打的就是负载均衡,网络通信,别的一些东西,都是次要,只要是看ribbon提供的各种负载均衡的算法的实现,另外一个是看ribbon + eureka + spring cloud如何整合使用的,看看ribbon源码里面去找比较重要的一些配置的参数