Ribbon 简介
分布式系统中, 各个微服务会部署多个实例, 如何将服务消费者均匀分摊到多个服务提供者实例上, 就要使用到负载均衡器
Ribbon 是负载均衡器, 它提供了很多负载均衡算法, 例如轮询随即等, 在配置服务提供者地址后, 可以将服务消费者请求均匀的分发
image
为服务消费者整合 Ribbon
添加 Ribbon 依赖库
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-ribbobn</artifactId>
- </dependency>
给 RestTemplate 添加 @LoadBalaced 注解, 就可整合 RestTemplate 和 Ribbon
- @Bean
- @LoadBalanced
- public RestTemplate restTemplate(){
- return new RestTemplate();
- }
修改 Controller, 请求地址修改为 http://flim-user/user/ , 当 Ribbon 和 Eureka 配合使用时, 会自动将虚拟主机名映射成微服务的网络地址, 并注入了 LoadBalancerClient 输出当前选择的微服务节点
- @RestController
- public class MovieController {
- private final Logger log = LoggerFactory.getLogger(MovieController.class);
- @Autowired
- private RestTemplate restTemplate;
- @Autowired
- private LoadBalancerClient loadBalancerClient;
- @GetMapping("/user/{id}")
- public User findById(@PathVariable int id){
- return this.restTemplate.getForObject("http://flim-user/"+id,User.class);
- }
- @GetMapping("/log-instance")
- public void logInstance(){
- ServiceInstance serviceInstance = this.loadBalancerClient.choose("flim-user");
- log.info("{}:{}:{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
- }
- }
运行测试程序
启动 Eureka Server
启动 2 个或更多 flim-user 实例
启动 flim-consumer
访问 http://localhost:8761/ 查看微服务 flim-user 是否注册成功
多次访问 http://localhost:8010/user/1 会返回如下结果
{"id":1,"username":"account1","name":"张三","age":20,"balance":100.00}
多次访问 http://localhost:8010/log-instance 控制台会输出以下信息
image
可以看到请求会均匀的分布到两个用户微服务上
- 2017-12-17 20:47:53.975 INFO 12313 --- [nio-8010-exec-2] com.linyuan.controller.MovieController : flim-user:linyuandembp:8764
- 2017-12-17 20:47:54.215 INFO 12313 --- [nio-8010-exec-1] com.linyuan.controller.MovieController : flim-user:linyuandembp:8763
- 2017-12-17 20:47:54.445 INFO 12313 --- [nio-8010-exec-3] com.linyuan.controller.MovieController : flim-user:linyuandembp:8764
- 2017-12-17 20:47:54.690 INFO 12313 --- [nio-8010-exec-4] com.linyuan.controller.MovieController : flim-user:linyuandembp:8763
- 2017-12-17 20:47:54.935 INFO 12313 --- [nio-8010-exec-5] com.linyuan.controller.MovieController : flim-user:linyuandembp:8764
注意: 不能将 restTemplate.getForObject(...) 与 loadBalancerClient.choose(...) 写在同一方法中, 因为 rest-Template 实际上就是一个 Ribbon 客户端, 本身已经包含 choose 行为
代码方式配置 Ribbon
可以使用 Java 代码或属性自定义 Ribbon 的配置, Ribbon 默认配置类是 RibbonClientConfiguration, 也可以使用一个 POJO 自定义 Ribbon 配置, 这种配置是细粒度的, 不同的 Ribbon 客户端可以使用不同的配置
创建 Ribbon 配置类
- /**
- * 该类为配置类
- * 不应该被 ComponentScan 扫描
- */
- @Configuration
- public class RibbonConfiguration {
- @Bean
- public IRule ribbonRule(){
- // 配置负载均衡的规则, 更改为随机
- return new RandomRule();
- }
- }
使用 @RibbonClient 或 @RibbonClients 注解为服务提供者指定配置类
- @SpringBootApplication
- @EnableDiscoveryClient
- @RibbonClient(name = "flim-user",configuration = RibbonConfiguration.class)
- public class FlimConsumerApplication {
- @Bean
- @LoadBalanced
- public RestTemplate restTemplate(){
- return new RestTemplate();
- }
- public static void main(String[] args) {
- SpringApplication.run(FlimConsumerApplication.class, args);
- }
- }
访问测试地址 http://localhost:8010/log-instance 可看见请求会随机分布到两微服务上
- 2017-12-17 21:08:52.769 INFO 12524 --- [nio-8010-exec-7] com.linyuan.controller.MovieController : flim-user:linyuandembp:8763
- 2017-12-17 21:08:52.946 INFO 12524 --- [nio-8010-exec-8] com.linyuan.controller.MovieController : flim-user:linyuandembp:8763
- 2017-12-17 21:08:53.138 INFO 12524 --- [nio-8010-exec-9] com.linyuan.controller.MovieController : flim-user:linyuandembp:8763
- 2017-12-17 21:08:53.319 INFO 12524 --- [io-8010-exec-10] com.linyuan.controller.MovieController : flim-user:linyuandembp:8764
- 2017-12-17 21:08:53.511 INFO 12524 --- [nio-8010-exec-1] com.linyuan.controller.MovieController : flim-user:linyuandembp:8763
注意: RibbonConfiguration 类不能被 @ComponentScan 扫描到, 否则配置信息就会被所有 @RibbonClient 共享, 因此如果只想自定义某个 Ribbon 客户端的配置, 必须防止被 @ComponentScan 扫描
配置文件方式配置 Ribbon
通过配置文件方式自定义 Ribbon 属性更加方便, 配置的前缀是 <clientName>.ribbon.
NFLoadBalancerClassName: 配置 ILoadBalancer 的实现类
NFLoadBalancerRuleClassName: 配置 IRule 的实现类
NFLoadBalancerPingClassName: 配置 IPing 实现类
NIWSServerListClassName: 配置 ServerList 的实现类
NIWSServerListFilterClassName: 配置 ServerListFilter 的实现类
通过配置文件定义 Ribbon 配置
- flim-user:
- ribbon:
- NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
常用的 Ribbon 全局配置
- ribbon:
- ConnectionTimeout: #连接超时时间
- ReadTimeout: #读取超时时间
- OkToRetryOnAllOperatotions: #对所有操作请求都进行重试
- MaxAutoRetriesNextServer: #切换服务器实例的重试次数
- MaxAutoRetries: #对当前实例的重试次数
- ServerListRefreshInterval: #刷新服务列表源的间隔时间
---- 待完善 ----
来源: http://www.jianshu.com/p/047ef2b7284f