经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Java » 查看文章
【分布式】SpringCloud(4)--Ribbon负载均衡
来源:cnblogs  作者:人无名,则可专心练剑  时间:2021/4/6 10:21:33  对本文有异议

1.Ribbon概述

1.1.Ribbon是什么

SpringCloud Ribbon是基于Netflix Ribbon实现的一套基于客户端Client的负载均衡工具

Ribbon主要的功能是提供客户端的软件负载均衡算法,将Netflix的中间层服务连接在一起,提供一系列完善的配置项如连接超时、重试等。

简单地说,就是在配置文件中列出Load Balancer(LB)后面所有的机器,Ribbon会自动地帮助你基于某种规则(如简单轮询、随机连接等)去连接这些机器。

 

1.2.负载均衡LB分类

集中式LB:

在服务的消费方和提供方之间使用独立的LB设施(可以是硬件(F5),也可以是软件(nginx)),由这些设施负责把访问请求通过某种策略转发至服务的提供方。(相当于公务员考公,国家选举)

进程内LB:

将LB的逻辑集成到消费方,消费方从服务注册中心获知有哪些地址可用,然后自己在从这些地址中选择出一个合适的服务器。(相当于客户点餐选择人少的取餐点取餐)

 

Ribbon就属于进程内LB,它只是一个类库,集成于消费方进程,消费方通过它来获取服务提供方的地址。

 

2.Ribbon 客户端配置

2.1.pom.xml

  1. <!--引入Ribbon相关:ribbon->eureka->config-->
  2. <dependency>
  3. <groupId>org.springframework.cloud</groupId>
  4. <artifactId>spring-cloud-starter-ribbon</artifactId>
  5. </dependency>
  6. <dependency>
  7. <groupId>org.springframework.cloud</groupId>
  8. <artifactId>spring-cloud-starter-config</artifactId>
  9. </dependency>
  10. <!--微服务provider方引入eureka-->
  11. <dependency>
  12. <groupId>org.springframework.cloud</groupId>
  13. <!--没有带sever表示就是client客户端-->
  14. <artifactId>spring-cloud-starter-eureka</artifactId>
  15. <version>1.4.6.RELEASE</version>
  16. </dependency>

 

2.2.application.yml

  1. server:
    #80端口被占用,选择了81测试
    port: 81

  1. #spring的配置
    spring:
    application:
    name: springcloud-consumer-dept #默认注册进eureka中的实例名称(显示大写)
    datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: org.gjt.mm.mysql.Driver
    url: jdbc:mysql://localhost:3306/springcloud_db01?useUnicode=true&characterEncoding=utf-8
    username: root
    password: admin
  1. #eureka的配置,确定客户端服务注册到eureka服务列表内
  2. eureka:
  3. client:
  4. register-with-eureka: false #不向eureka注册自己
  5. service-url: #使用eureka集群测试
  6. defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

 

2.3.启动类及配置类

在consumer客户端的配置类上加上@LoadBanlanced,表示当前的请求在客户端做负载均衡;

  1. @Configuration
  2. public class SpringBeanConfig {
  3. @Bean
  4. @LoadBalanced //Ribbon基于客户端做负载均衡
  5. public RestTemplate getRestTemplate(){
  6. return new RestTemplate();
  7. }
  8. }

 

  1. @RestController
  2. public class DeptConsumerController {
  3. @Autowired
  4. private RestTemplate restTemplate;
  5. //服务端的请求地址,这里是本机localhost,也可以是其他任意的服务机ip地址
  6. //private static final String REST_URL_PREFIX = "http://localhost:8001";
  7. //负载均衡后通过服务名来获取,因为由客户端选举定位到随机的一个Eureka注册中心去访问
  8. private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
  9. }

启动测试访问接口:http://localhost:8002/consumer/dept/get/2,访问成功。

 

总结:Ribbon和Eureka整合后consumer可以直接调用服务而不用关心地址和端口号。

 

3.Ribbon负载均衡配置

Ribbon的负载均衡实现策略主要有:轮询、随机、重试三种。下面演示Ribbon的负载均衡,采用创建三个服务提供方的方式,并启用三个Eureka服务注册地址。具体思路图如下:

 

3.1.请求提供者Provider创建

这里每个请求者都是一个单体服务,拥有自己独立的数据库,访问接口。但是提供暴露到注册中心的实例名是唯一的,用于客户端来做访问地址的唯一请求,而Ribbon则会通过@LoadBalanced注解对应识别客户端请求查询可用的服务列表,调用对应的负载均衡策略。

(1)单个的provider中主要的application.yml配置:

 

  1. server:
  2. port: 8001
  3. #mybatis的配置
  4. mybatis:
  5. type-aliases-package: com.fengye.springcloud.pojo
  6. mapper-locations: classpath:mybatis/mapper/*Mapper.xml
  7. configuration:
  8. map-underscore-to-camel-case: true
  9. #spring的配置
  10. spring:
  11. application:
  12. name: springcloud-provider-dept #默认注册进eureka中的实例名称(多个服务提供方应该唯一)
  13. datasource:
  14. type: com.alibaba.druid.pool.DruidDataSource
  15. driver-class-name: org.gjt.mm.mysql.Driver
  16. url: jdbc:mysql://localhost:3306/springcloud_db01?useUnicode=true&characterEncoding=utf-8 #db01/02/03
  17. username: root
  18. password: admin
  19. #eureka的配置,确定客户端服务注册到eureka服务列表内
  20. eureka:
  21. client:
  22. service-url:
  23. #集群配置
  24. defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

 

(2)在服务提供方provider的Controller设置请求的调用接口,同时设置负载均衡端口信息:

  1. @RestController
  2. @RequestMapping("/dept")
  3. public class DeptController {
  4. @Autowired
  5. private DeptService service;
  6. //集群情况下,用于订单服务查看到底调用的是哪个商品微服务节点
  7. @Value("${server.port}")
  8. private String port;
  9. @GetMapping("/queryById/{id}")
  10. public Dept queryById(@PathVariable("id") Long id){
  11. Dept dept = service.queryById(id);
  12. Dept result = new Dept();
  13. BeanUtils.copyProperties(dept, result);
  14. result.setDname(result.getDname() + " data from port=" + port); //查看员工属于哪个端口
  15. System.out.println(result.getDname());
  16. return result;
  17. };
  18. }

 

3.2.服务调用方接收并测试

(1)请求调用controller接口编写:

  1. @RestController
  2. public class DeptConsumerController {
  3. /**
  4. * 消费者:不应该有service实现层
  5. * RestTemplate:提供多种便捷的访问远程http服务的方法,提供简单的restful服务模板(使用简单无脑粗暴)
  6. * 参数类型:(url, requestMap, ResponseBean.class)分别代表REST请求地址、请求参数、HTTP响应转换被转换成的对象类型
  7. */
  8. @Autowired
  9. private RestTemplate restTemplate;
  10. //负载均衡后通过服务名来获取
  11. private static final String REST_URL_PREFIX = "http://SPRINGCLOUD-PROVIDER-DEPT";
  12. @RequestMapping("/consumer/dept/get/{id}")
  13. public Dept get(@PathVariable("id") Long id){
  14. Dept result = restTemplate.getForObject(REST_URL_PREFIX + "/dept/queryById/" + id, Dept.class);
  15. System.out.println("客户端请求:data from port= " + result.getDname());
  16. return result;
  17. }
  18. }

 

(2)服务调用方获取并请求调用请求端口,获取并打印访问的端口信息,连续多请求几次:

 

控制台打印:

 

 

可以看到每次访问请求的端口都在不停变化,客户端consumer基于Ribbon实现了负载均衡

 

Ribbon文档相关:

https://github.com/Netflix/ribbon

 

示例代码已上传至Github地址:

https://github.com/devyf/SpringCloud_Study/tree/main/springcloud_hello

 

原文链接:http://www.cnblogs.com/yif0118/p/14612988.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号