一、认识Ribbon
1.1、介绍Ribbon
Spring Cloud Ribbon 是一个基于 HTTP 和 TCP 的客户端负载均衡工具,它基于 Netflix Ribbon 实现。通过 Spring Cloud 的封装,可以
让我们轻松地将面向服务的 REST 模版请求 自动转换成客户端负载均衡的服务调用。 轮询 hash 权重 …
简单的说 Ribbon 就是 netfix 公司的一个开源项目,主要功能是提供客户端负载均衡算法和 服务调用。
Ribbon 客户端组件提供了一套完善的配置项,比如连接超时,重试等。 在 Spring Cloud 构建的微服务系统中, Ribbon 作为服务消费者的负载均衡器,有两种使 用方式,一种是和 RestTemplate 相结合,另一种是和 OpenFeign 相结合。
OpenFeign 已经 默认集成了 Ribbon,关于 OpenFeign 的内容将会在下一章进行详细讲解。Ribbon 有很多子 模块,但很多模块没有用于生产环境!
1.2、负载均衡协议
负载均衡,英文名称为 Load Balance(LB)http:// lb://(负载均衡协议) ,其含义就是指将负载(工作任务)进行平衡、分摊到多个操作单元上进行运行,例如 Web 服务器、 企业核心应用服务器和其它主要任务服务器等,从而协同完成工作任务。
负载均衡构建在原有网络结构之上,它提供了一种透明且廉价有效的方法扩展服务器和网络设备的带宽、加强网络数据处理能力、增加吞吐量、提高网络的可用性和灵活性。
服务器的负载均衡
二、实战—快速集成Ribbon组件
目标:借助使用Ribbon组件集成到SpringCloud实现负载均衡【针对于某个服务的集群模式】。
项目版本环境:
SpringBoot:2.3.12.RELEASE
SpringCloud:Hoxton.SR12
2.1、前提准备(provider生产者)
想要完成这一个ribbondemo,首先需要准备一个Eureka Server服务端,还有两个provider生产端。
Eureake-Server使用的时之前的案例demo,然后最新的两个生产方则时最新创建的。其实这两个provider本质就是两个Eureka-client,在启动时都会注册到Server服务端中。
创建两个provider的流程与之前的相同,这里给出两个配置文件以及各自暴露的接口:
① provider-a: application.yml: server: port: 8080 spring: application: name: provider eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: hostname: locahost prefer-ip-address: true instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
controller/ProviderController.java:
package com.changlu.ribbonprovidera.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @Description: * @Author: changlu * @Date: 4:58 PM */ @RestController public class ProviderController { @GetMapping("/hello") public String hello(){ return "我是服务提供者aaa"; } }
②provider-b:
application.yml: server: port: 8081 spring: application: name: provider eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: hostname: localhost prefer-ip-address: true instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
controller/ProviderController.java:
package com.changlu.ribbonproviderb.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; /** * @Description: * @Author: changlu * @Date: 4:58 PM */ @RestController public class ProviderController { @GetMapping("/hello") public String hello(){ return "我是服务提供者bbb"; } }
暴露的接口返回的不是同一个内容,主要目的是为了之后的测试。
我们将这三个服务启动起来:
访问:http://localhost:8761/
可以看到此时provider应用有两个服务,之后我们的目标就是这个provider应用对其进行负载均衡:
2.2、创建消费者consumer
创建一个Eureka-Client项目:
SpringBoot:2.3.1.RELEASE SpringCloud:Hoxton.SR12 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency>
配置如下:
server: port: 8082 spring: application: name: consumer eureka: client: service-url: defaultZone: http://localhost:8761/eureka instance: hostname: localhost prefer-ip-address: true instance-id: ${eureka.instance.hostname}:${spring.application.name}:${server.port}
开启EureakClient:
@EnableEurekaClient
2.3、消费者集成Ribbon组件(两种方案)
前提
若是我们想要实现一个负载均衡的功能,那么我们引入netflix的ribbon依赖:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency>
实践
方式一:增强RestTemplate方法,使其具备负载均衡功能。
如何增强呢?我们来RestTemplate来在注入过程中进行增强。
package com.changlu.ribbonconsumer.config; import org.springframework.cloud.client.loadbalancer.LoadBalanced; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.client.RestTemplate; /** * @Description: 个人配置类 * @Author: changlu * @Date: 5:03 PM */ @Configuration public class MyConfig { @Bean @LoadBalanced //使用负载均衡器 public RestTemplate restTemplate() { return new RestTemplate(); } }
controller/ConsumerController.java:
package com.changlu.ribbonconsumer.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; /** * @Description: * @Author: changlu * @Date: 4:56 PM */ @RestController public class ConsumerController { //方式一:增强版的RestTemplate(附带负载均衡) @Autowired private RestTemplate restTemplate; @GetMapping("/testRibbon") public String testRibbon(String serviceId) { String url = "http://" + serviceId + "/hello"; String content = restTemplate.getForObject(url, String.class); return content; } }
启动服务后我们来进行测试:http://localhost:8082/testRibbon?serviceId=provider
思路如下:
思考 ribbon是怎么将 http://provider/hello 路径请求成功的【本质:对服务名来进行服务发现并进行替换发送请求】 1.拦截这个请求 2.截取主机名称 3.借助eureka来做服务发现 list<> (127.0.0.1:8080、127.0.0.1:8081) 4.通过负载均衡算法 拿到一个服务ip port,举例如:http://127.0.0.1:8080/hello 5.reConstructURL
方法二:直接使用ribbon给我们提供的客户端
package com.changlu.ribbonconsumer.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.ServiceInstance; import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; /** * @Description: * @Author: changlu * @Date: 4:56 PM */ @RestController public class ConsumerController { //方式二:使用ribbon提供的客户端来进行负载均衡获取服务 @Autowired private LoadBalancerClient loadBalancerClient; @GetMapping("/testRibbon2") public String testRibbon2(String serviceId) { //根据服务来进行选择一个实例 ServiceInstance choose = loadBalancerClient.choose(serviceId); return choose.toString(); } }
访问路径:http://localhost:8082/testRibbon2?serviceId=provider