当前位置:网站首页>Ribbon负载均衡的深度分析和使用
Ribbon负载均衡的深度分析和使用
2022-08-02 12:49:00 【良月生秋】
前言:
本篇文章主要介绍Ribbon负载均衡的使用,策略及原理,希望能加深自己的印象以及帮助各位大佬???
如果文章有什么需要改进的地方还请大佬多多指正
小威在这里先感谢各位大佬了???

文章目录
??Ribbon负载均衡使用
接着上一篇文章的来,运用负载均衡的注解 @LoadBalanced进行管理
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
??Ribbon项目使用流程

- 拦截我们的RestTemplate请求http://userservice/user/1
- RibbonLoadBalancerClient会从请求url中获取服务名称,也就是user-service
- DynamicServerListLoadBalancer根据user-service到eureka拉取服务列表
- eureka返回列表,localhost:8081、localhost:8082
- IRule利用内置负载均衡规则,从列表中选择一个,例如localhost:8081
- RibbonLoadBalancerClient修改请求地址,用localhost:8081替代userservice,得到http://localhost:8081/user/1,发起真实请求
??Ribbon负载均衡分析
负载均衡拦截器实现客户端http请求拦截器(ClientHttpRequestInterceptor)并重写方法
public class LoadBalancerInterceptor implements ClientHttpRequestInterceptor {
private LoadBalancerClient loadBalancer;
private LoadBalancerRequestFactory requestFactory;
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer, LoadBalancerRequestFactory requestFactory) {
this.loadBalancer = loadBalancer;
this.requestFactory = requestFactory;
}
public LoadBalancerInterceptor(LoadBalancerClient loadBalancer) {
this(loadBalancer, new LoadBalancerRequestFactory(loadBalancer));
}
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body, final ClientHttpRequestExecution execution) throws IOException {
URI originalUri = request.getURI();
String serviceName = originalUri.getHost();
Assert.state(serviceName != null, "Request URI does not contain a valid hostname: " + originalUri);
return (ClientHttpResponse)this.loadBalancer.execute(serviceName, this.requestFactory.createRequest(request, body, execution));
}
}
找到Eureka服务列表并根据负载均衡算法选取一个服务
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint) throws IOException {
ILoadBalancer loadBalancer = this.getLoadBalancer(serviceId);//根据服务名称找Eureka服务列表
Server server = this.getServer(loadBalancer, hint);//根据负载均衡算法从Eureka的server列表中选出一个
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
} else {
RibbonLoadBalancerClient.RibbonServer ribbonServer = new RibbonLoadBalancerClient.RibbonServer(serviceId, server, this.isSecure(server, serviceId), this.serverIntrospector(serviceId).getMetadata(server));
return this.execute(serviceId, (ServiceInstance)ribbonServer, (LoadBalancerRequest)request);
}
}
getLoadBalancer(serviceId):根据服务id获取ILoadBalancer,而ILoadBalancer会拿着服务id去eureka中获取服务列表并保存起来。getServer(loadBalancer):利用内置的负载均衡算法,从服务列表中选择一个。
在BaseLoadBalancer.class的类下,利用IRule实现负载均衡的策略
跟进上面的getServer方法,继续跟踪源码在BaseLoadBalancer类下找到chooseServer方法
public Server chooseServer(Object key) {
if (this.counter == null) {
this.counter = this.createCounter();
}
this.counter.increment();
if (this.rule == null) {
return null;
} else {
try {
return this.rule.choose(key);//进行服务选择的Key
} catch (Exception var3) {
logger.warn("LoadBalancer [{}]: Error choosing server for key {}", new Object[]{this.name, key, var3});
return null;
}
}
}
??Ribbon负载均衡策略
跟进上面的rule,rule,规则,即负载均衡的规则,有以下几种
public class BaseLoadBalancer extends AbstractLoadBalancer implements PrimeConnectionListener, IClientConfigAware {
private static Logger logger = LoggerFactory.getLogger(BaseLoadBalancer.class);
private static final IRule DEFAULT_RULE = new RoundRobinRule();//这里的rule默认值是一个`RoundRobinRule`的类型
private static final BaseLoadBalancer.SerialPingStrategy DEFAULT_PING_STRATEGY = new BaseLoadBalancer.SerialPingStrategy((SyntheticClass_1)null);
private static final String DEFAULT_NAME = "default";
private static final String PREFIX = "LoadBalancer_";
protected IRule rule;
protected IPingStrategy pingStrategy;
protected IPing ping;


RoundRobinRule(轮询策略):按照一定的顺序依次调用服务实例。多个服务轮流访问。它是Ribbon默认的负载均衡规则。
RandomRule(随机策略):从服务提供者的列表中随机选择一个服务实例。
WeightedResponseTimeRule(权重策略):根据每个服务提供者的响应时间分配个权重,响应时间越长,权重越小,被选中的可能性也就越低。
RetryRule(重试策略):按照轮询策略来获取服务,如果获取的服务实例为 null 或已经失效,则在指定的时间之内不断地进行重试来获取服务,如果超过指定时间依然没获取到服务实例则返回 null。
AvailabilityFilteringRule(可敏感性策略):先过滤掉健康的服务实例,然后再选择连接数较的服务实例。
ZoneAvoidanceRule(区域敏感策略):根据服务所在区域(zone)的性能和服务的可性来选择服务实例,在没有区域的环境下,该策略和轮询策略类似。
BestAvailableRule(最小连接数策略):也叫最小并发数策略,它是遍历服务提供者列表,选取连接数最小的个服务实例。如果有相同的最连接数,那么会调轮询策略进行选取。即忽略那些短路的服务器,并选择并发数较低的服务器。
??自定义负载均衡策略
我们需要在order-service中的OrderApplication类中,定义一个新的IRule:
@Bean
public IRule randomRule(){
return new RandomRule();
}
配置文件方式:在order-service的application.yml文件中,添加新的配置也可以修改规则:
userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
??Ribbon设置饥饿加载
Ribbon默认是采用懒加载,就是第一次访问的时候才会去创建LoadBalanceClient,这样的情况下会导致请求时间很长,影响我们的使用效率。
而饥饿加载则会在项目启动时创建,降低第一次访问的耗时,以下是开启饥饿加载的配置
ribbon:
eager-load:
enabled: true
clients: userservice
本文到此结束,希望能帮到各位小伙伴儿???
如果文章有什么需要改进的地方还请大佬多多指教???
以下是我的V信,欢迎加入我们的圈子???
再次感谢各位大佬???
先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦
边栏推荐
- Four seasons of trees realized by svg
- 【The 6th Strong Net Cup CTF-Wp】
- Chapter 11 Documents
- ThinkPHP 5.1反序列化分析和poc
- Intelligent Image Analysis-Intelligent Home Appliance Image Target Detection Statistical Counting Detection and Recognition-iCREDIT
- LeetCode_139_单词拆分
- 瀑布流式布局怎么实现(什么是瀑布流布局)
- Drools(8): WorkBench uses
- js true 3d histogram plugin
- 如何关闭开启硬件加速[通俗易懂]
猜你喜欢
随机推荐
linux basic command explanation
路由-Tab切换页面
Speed up your programs with bitwise operations
麻烦问一下,对mysql 场景注入故障,是不是不是对mysql server 端注入故障,只是对ja
SQL Server 2014 installation tutorial (nanny-level graphic tutorial)
OpenFeign设置header的3种方式
Js scratchable latex style draw plug-in
新特性解读 | MySQL 8.0 GIPK 不可见主键
package.json and package-lock.json
瀑布流式布局怎么实现(什么是瀑布流布局)
Do you really understand the business process service BPass?
汉源高科千兆12光12电管理型工业以太网交换机 12千兆光12千兆电口宽温环网交换机
软件成分分析:手握5大能力守护软件供应链安全
路由-嵌套路由
水平垂直居中方式
Taurus.MVC V3.0.3 Microservice Open Source Framework Released: Make the evolution of .NET architecture easier in large concurrency.
ssm访问数据库数据报错
LeetCode_377_组合总和Ⅳ
There are several ways to jump to js source code, jump on the current page, jump on the blank page
How to implement waterfall flow layout (what is waterfall flow layout)









