Eureka 和 Ribbon
上次学习了 Eureka 服务的注册和调用,当某个服务搭建了多实例,共同注册到了 Eureka 上,那么 Eureka 是如何把消费者们的请求均衡到这些多个实例的呢?今天来学习下 Eureka 负载均衡相关的东西。
使用 Feign
新建 eureka-provider1的 SpringBoot 项目
启动类
添加@EnableEurekaCLient
注解
1 |
|
配置文件
1 | server: |
Controller
1 |
|
eureka-provider项目的controller修改返回内容
1 |
|
这样同一个服务“provider”有两个实例,启动 注册中心server,两个服务提供者、消费者项目,访问http://localhsot:10000/hello ,进行测试:
发现第一次返回:hello! Yakai! from provider
第二次返回:hello! Yakai! from provider1
第三次:hello! Yakai! from provider
第四次:hello! Yakai! from provider1
……
发现两种结果交替出现,说明 Eureka 服务中心提供了负载均衡的功能,当然,两台实例不足以证明是轮询负载均衡的结论,当不断增加实例时,发现每个实例依然是按顺序被调用后,这说明 使用 Fegin 远程调用,请求是默认自动轮询到服务的每个实例来处理。
使用 Ribbon
Ribbon 简介
Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer 后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随即连接等)去连接这些机器。我们也很容易使用Ribbon实现自定义的负载均衡算法。
Ribbon 的组件
ServerList
- 用于获取地址列表。它既可以是静态的(提供一组固定的地址),也可以是动态的(从注册中心中定期查询地址列表)。
ServerListFilter
- 仅当使用动态ServerList时使用,用于在原始的服务列表中使用一定策略过虑掉一部分地址。
IRule
- 选择一个
- 最终的服务地址作为负载均衡结果。选择策略有轮询、根据响应时间加权、断路器(当Hystrix可用时)等。
Ribbon 的工作流程
Ribbon在工作时首选会通过ServerList来获取所有可用的服务列表,然后通过ServerListFilter过虑掉一部分地址,最后在剩下的地址中通过IRule选择出一台服务器作为最终结果,和Dubbo 的负载均衡流程有点类似。
Ribbon 主要负载均衡策略
轮询(RoundRobin)
随机(Random)
加权响应时间负载均衡 (WeightedResponseTime)
根据响应时间分配一个weight,相应时间越长,weight越小,被选中的可能性越低。
区域感知轮询负载均衡(ZoneAvoidanceRule)
复合判断server所在区域的性能和server的可用性选择server
实现负载均衡
看图了解到,Ribbon 存在于消费者端,也就是客户端
测试 Ribbon
原provider不变,新建eureka-consumer-ribbon 项目
引入依赖
其实 Fegin、eureka-server 已经集成了 Ribbon,这里引入 eureka-server 即可
1 | <dependency> |
开启 Ribbon 的负载均衡
1 |
|
消费者controller
在这里直接用程序名(spring.application.provider)替代了具体的url地址,在 Ribbon 中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的url替换掉服务名:
一般来讲, RestTemplate 应该在 service 层注入,然后 controller 层调 service,service 可再进行一些逻辑处理,这里为了省事直接注入到了 controller 层。
1 |
|
启动相关项目,访问 http://localhost:10001/hello 查看显示内容:
发现第一次返回:hello! Yakai! from provider
第二次返回:hello! Yakai! from provider1
第三次:hello! Yakai! from provider
第四次:hello! Yakai! from provider1
发现 Ribbon 的默认负载均衡也是轮询。
自定义 Ribbon 客户端
上面测试知道,Ribbon 默认的负载均衡策略是轮询,如果想改变其默认策略,比如使用随机该怎样配置?
这就需要自定义 Ribbon 配置类,但是官方文档警告:这个测试配置类不能放在@ComponentScan所扫描的当前包下以及子包下,否则自定义的这个配置类就会被所有的Ribbon客户端(@RibbonClient)所共享,这样达不到特殊定制化了。
在学习 SpringBoot 后知道,@SpringBootApplication注解里集成了@ComponentScan,它会自动扫描该注解的启动类所在的包以及该包的子包都将被所有 Ribbon 客户端所共享。
解决方法:
1.新建一个不在 @ComponentScan扫描下的包,在这个包下创建 Ribbon 配置类。
2.仍在启动类所在的包下或子包下创建启动 Ribbon 配置类,但排除@ComponentScan扫描,可以使用自定义注解的方式。
我使用的是第二种方法,一是代码结构清晰,二是在 Ribbon 配置类中可以不用再注入IClientConfig
类
自定义忽略@ComponentScan扫描的注解
1 | public IgnoreCompnentScan { |
Ribbon 配置类
1 |
|
启动类
1 |
|
启动相关程序,访问 http://localhsot:10001/hello,并多次刷新,发现返回的内容不再是有序出现,因为使用了 RandomRule
,导致每次调用返回的内容都是随机的。
除此用代码配置 Ribbon 配置类的方式外,还可以配置文件的方式,二者都可以。
- Title: Eureka 和 Ribbon
- Author: 薛定谔的汪
- Created at : 2018-06-01 18:20:16
- Updated at : 2023-11-17 19:37:36
- Link: https://www.zhengyk.cn/2018/06/01/springcloud/load-balance/
- License: This work is licensed under CC BY-NC-SA 4.0.