使用Ribbon实现客户端负载均衡

时间:2022-06-17
本文章向大家介绍使用Ribbon实现客户端负载均衡,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

一、使用Ribbon实现客户端负载均衡

经过前文的讲解, 已经实现了微服务的 注册与发现。启 动各个微服务时 , Eureka Client会把自己的网络信息注册到 Eureka Server 上。世界似乎更美好了一些。 然而,这样的架构依然有一些问题,比 如负载均衡。一般来说,在生产环境中,各个微服务都会部署多个实例。那么服务消费者要如何将请求分摊到多个服务提供者实例上呢?

1.1 Ribbon 简介

ribbon 是 Netflix 发布的负载均衡器,它 有助于控制 HTTP 和 TCP 客户端的行为。为ribbon 配置服务提供者地址列表后 , Ribbon 就可基于某种负载均衡算法, 自动地帮助服务消费者去请求。 Ribbon 默认为我们提供了很多的负载均衡算法, 例如轮询、随机等。当然, 我们也可为 Ribbon 实现自定义的负载均衡算法。 在 Spring Cloud 中, 当 ribbon 与 Eureka 配合使用时, Ribbon 可自动从 Eureka Server 获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。

1.2 为服务消费者整合Ribbon 本节来为前文编写的电影微服务整合 Ribbon。

  1. 复制项目 consmuer­ 项目
  2. 为项目引入 Ribbon的依赖, Ribbon的依赖是: 由于前文中巳为电影微服务添加了spring-cloud-starter-eureka , 该依赖已经包含了spring-cloud-starter-ribbon , 所以尤须再次引入。
 	 <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
  1. 为 RestTemplate添加创LoadBalanced 注解。 回顾以前的代码,使用如下方法实例化 RestTemplate:
@SpringBootApplication
		@EnableEurekaClient
		public class SpringCustomerApplication {
		
			@LoadBalanced
			@Bean
			public RestTemplate restTemplate() {
				return new RestTemplate();
			}
			
			public static void main(String[] args) {
				SpringApplication.run(SpringCustomerApplication.class, args);
			}
		}
	为服务消费者整合 Ribbon两者对比可以发现,只 须 添加LoadBalanced 注解,就 可为 RestTemplate整合Rib­ban, 使其具备负载均衡的能力。
  1. 将 Controller 代码修改如下:
@RestController
		public class MovieController {
		
			private static final Logger logger = LoggerFactory.getLogger(MovieController.class);
				
			@Autowired
			private RestTemplate restTemplate;
				
			@Value("${user.userServiceUrl}")
			private String userServiceUrl;
				
			@Autowired
			private LoadBalancerClient loadBalancerClient;
				
			@GetMapping("/user/{id}")
			public User findById(@PathVariable Long id) {
				return this.restTemplate.getForObject("http://cloud/" + id, User.class);
				//return this.restTemplate.getForObject("http://localhost:8000/" + id, User.class);
				//return this.restTemplate.getForObject(this.userServiceUrl + id, User.class);
			}
				
			@GetMapping("/log_user_instance")
			public void logUserInstance() {
				ServiceInstance serviceInstance = this.loadBalancerClient.choose("cloud");
				MovieController.logger.info("{}:{};{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
			}
		}
	由代码可知, 我们将请求的地址改成了http://cloud/ 。
	cloud 是用户微服务的虚拟主机名 ( virtual host name) , 当ribbon 和  Eureka   配合使用时, 会自动将虚拟主机名映射成微服务的网络地址。
	在新增的logUserInstance( ) 方法中可使用LoadBalancerClient 的 API 更加直观地获取当前选择的用户微服务节点。

测试

1.	启动 discovery-eureka。
2.	启动 2 个或更多provinder实例。
3.	启动一个consumer。
4.	用consumer访问provinder,查看访问provinder的方式。

我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=1qfejm37rewql