深入理解Java|深入理解Java SpringCloud Ribbon 负载均衡
目录
- 前言
- 1、抛出问题
- 2、源码解析
- 2.1、LoadBalancerIntercepor
- 2.2、LoadBalancerClient
- 2.3、负载均衡策略IRule
- 2.4、总结
- 3、负载均衡策略
- 总结
前言
该技术博客是关于黑马视频教程的笔记总结!服务消费者需要通过
RestTemplate
调用注册中心(Eureka)的服务提供者,但当同一服务名称的服务有多个的时候,我们的服务消费者应该调用哪一个服务呢?这时候就需要我们学习理解Ribbon负载均衡的实现原理。当我们在RestTemplate组件上加上
@LoadBalanced
注解,就会去注册中心中拉取服务的实例列表,并且实现负载均衡,SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。1、抛出问题 比如我们的服务消费者 order-service发出请求:http://userservice/user/1
该请求并不能与注册中心中的服务列表信息相符,那么是如何找到 http://localhost:8081呢?
文章图片
2、源码解析
2.1、LoadBalancerIntercepor
上述信息已经表明,我们没有输出IP和端口号,只是通过了服务名称(userservice) 就能找到我们想要调用的服务!
这是因为Ribbon组件中的
LoadBalancerInterceptor(负载均衡拦截器)
会将调用请求拦截,根据服务名称获取到服务实例的ip和端口。LoadBalancerInterceptor 会在将RestTemplate的请求进行拦截,然后在Eureka注册中心根据
服务名称
获取服务列表
,随后利用负载均衡算法
得到真实的服务地址信息,替换服务名称。文章图片
可以看到这里的intercept方法,拦截了调用请求HttpRequest,然后做了一下操作:
1
.request.getURI():
获取请求uri,本例中就是 http://user-service/user/82.
originalUri.getHost():
获取uri路径的主机名,其实就是服名称:userservice
3.
this.loadBalancer.execute():
处理服务名称,和用户请求这里的this.loadBalancer是LoadBalancerClient类型,我们继续跟入execute方法!
2.2、LoadBalancerClient
代码是这样的:
getLoadBalancer(serviceId):根据服务名称获取
ILoadBalancer
接口,而ILoadBalancer
会拿着服务名称去eureka中获取服务列表并保存起来。getServer(loadBalancer):利用内置的负载均衡算法,从服务列表中选择一个。本例中,可以看到获取了8082端口的服务
文章图片
放行后,再次访问并跟踪,发现变成获取8081端口服务,实现了负载均衡:
文章图片
2.3、负载均衡策略IRule
在刚才的代码中,可以看到获取服务使通过一个getServer方法来做负载均衡:
文章图片
继续跟入getServer方法:
文章图片
继续跟踪源码chooseServer方法,发现这么一段代码:
文章图片
我们看看这个rule是谁:
文章图片
这里的rule默认值是一个RoundRobinRule,看看介绍:
文章图片
翻译过来就是轮询的意思,这样,整个负载均衡的流程我们就清楚了。
2.4、总结
Ribbon的底层采用了一个拦截器,拦截了RestTemplate发出的请求,对地址做了修改。用一幅图来总结一下:
文章图片
基本流程如下:
- 拦截我们的RestTemplate请求http://userservice/user/1
- RibbonLoadBalancerClient会从请求url中获取服务名称,也就是userservice
- DynamicServerListLoadBalancer根据userservice到eureka拉取服务列表:localhost:8081、localhost:8082
- IRule利用内置负载均衡规则,从列表中选择一个服务,例如localhost:8081
- RibbonLoadBalancerClient修改请求地址,用localhost:8081替代userservice,得到http://localhost:8081/user/1,发起真实请求
3、负载均衡策略 负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类:
文章图片
不同规则的含义如下:
文章图片
默认的实现就是ZoneAvoidanceRule,是一种轮询方案
那么如何自定义负载均衡策略?
通过定义IRule实现可以修改负载均衡规则,有两种方式:
1.代码方式:在配置类或启动类(可以看作配置类)中,定义一个新的IRule:
@Beanpublic IRule randomRule(){ //随机策略return new RandomRule(); }
配置文件方式:在application.yml文件中,添加新的配置也可以修改规则:
userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
注意:我们一般用默认的负载均衡规则,不做修改!
总结 【深入理解Java|深入理解Java SpringCloud Ribbon 负载均衡】本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注脚本之家的更多内容!
推荐阅读
- JAVA(抽象类与接口的区别&重载与重写&内存泄漏)
- 深入理解Go之generate
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- 由浅入深理解AOP
- 事件代理
- 逻辑回归的理解与python示例
- Java|Java OpenCV图像处理之SIFT角点检测详解
- java中如何实现重建二叉树
- 【1057快报】深入机关,走下田间,交通普法,共创文明
- 数组常用方法一