4.SpringCloud组件之Ribbn
[toc]
Ribbon
我们启动了一个justweb-service-provider,然后通过DiscoveryClient来获取服务实例信息,然后获取ip和端口来访问。
但是实际环境中,我们往往会开启很多个justweb-service-provider的集群。此时我们获取的服务列表中就会有多个,到底该访问哪一个呢?
一般这种情况下我们就需要编写负载均衡算法,在多个实例列表中进行选择。
Eureka中已经帮我们集成了负载均衡组件:Ribbon,简单修改代码即可使用。
1. Ribbn简介
- 轮询
- 随机
2. 启动两个服务实例
首先参照justweb-eureka启动两个justwebServiceProviderApplication实例,一个8081,一个8082。
Eureka监控面板:
3. 开启负载均衡
因为Eureka中已经集成了Ribbon,所以我们无需引入新的依赖,直接修改代码。
修改justweb-service-consumer的引导类
,在RestTemplate的配置方法上添加@LoadBalanced
注解
1 |
|
修改调用方式,不再手动获取ip和端口,而是直接通过服务名称调用
1 |
|
4. 负载均衡策略
Ribbon默认的负载均衡策略是简单的轮询,我们可以测试一下:
编写测试类,在刚才的源码中我们看到拦截中是使用RibbonLoadBalanceClient来进行负载均衡的,其中有一个choose方法,找到choose方法的接口方法,是这样介绍的:
现在这个就是负载均衡获取实例的方法。
4.1 修改负载均衡的策略
接口IRule:定义负载均衡的规则接口。这里的IRule默值是一个
RoundRobinRule
,看类的介绍:
SpringBoot也帮我们提供了修改负载均衡规则的配置入口,在justweb-service-consumer的application.yml中添加如下配置:
- 格式是:
{服务名称}.ribbon.NFLoadBalancerRuleClassName
,值就是IRule的实现类(properties格式)
。
1 | service-provider: |
5. 源码跟踪
为什么我们只输入了service名称就可以访问了呢?之前还要获取ip和端口。显然有人帮我们根据service名称,获取到了服务实例的ip和端口。它就是
LoadBalancerInterceptor
在如下代码打断点:
一路源码跟踪:RestTemplate.getForObject --> RestTemplate.execute --> RestTemplate.doExecute:
点击进入AbstractClientHttpRequest.execute --> AbstractBufferingClientHttpRequest.executeInternal --> InterceptingClientHttpRequest.executeInternal --> InterceptingClientHttpRequest.execute:
继续跟入:LoadBalancerInterceptor.intercept方法
继续跟入execute方法:发现获取了8082端口的服务
再跟下一次,发现获取的是8081: