当前位置:网站首页>使用 Ribbon 实现客户端负载均衡
使用 Ribbon 实现客户端负载均衡
2022-06-11 10:32:00 【chentian114】
使用 Ribbon 实现客户端负载均衡
前言
在前文《使用Eureka提供服务注册与发现》https://mp.weixin.qq.com/s/L2Tx6Lk0jl6GW-g0SeUXyw 中,通过基于 Eureka 实现服务注册与发现。一般来说,在生产环境中,各个微服务都会部署多个实例,那么服务消费者要如何将请求分摊到多个服务提供者实例上呢?
在 Spring Cloud 中,当 Ribbon 和 Eureka 配合使用时,Ribbon 可自动从 Eureka Server 获取服务提供者地址列表,并基于负载均衡算法,请求其中一个服务提供者实例。
Ribbon 简介
Ribbon 是 Netflix 发布的负载均衡器,它有助于控制 HTTP 和 TCP 客户端的行为。为 Ribbon 配置服务提供者地址列表后, Ribbon 就可基于某种负载均衡算法,自动地帮助服务消费者去请求。 Ribbon 默认为我们提供了很多的负载均衡算法,例如轮询、随机等。当然,我们也可为 Ribbon 实现自定义的负载均衡算法。

为服务消费者整合 Ribbon
创建项目,复制项目 micro-consumer-movie ,将 artifactId 修改为 micro-consumer-movie-ribbon 。
为项目引入 Ribbon 的依赖,spring-cloud-starter-eureka 默认包含了 Ribbon 的依赖 spring-cloud-starter-ribbon 。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
- 为 RestTemplate 添加
@LoadBalance注解,就可为 RestTemplate 整合 Ribbon ,使其具备负载均衡的能力。
@Configuration
public class RestConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
- 启动 Eureka Server 注册中心 和 多个服务提供者 micro-provider-user 。
java -jar micro-discovery-eureka-0.0.1-SNAPSHOT.jar
java -jar micro-provider-user-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar micro-provider-user-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
- 修改服务消费者调用服务提供者的请求地址,http://localhost:8000/ 改为 http://micro-provider-user/ 。
@RestController
@RequestMapping("/movie/v1")
public class MovieController {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Resource
private RestTemplate restTemplate;
@Resource
private LoadBalancerClient loadBalancerClient;
@GetMapping("/{id}")
public User findById(@PathVariable Long id){
User entity = restTemplate.getForObject("http://micro-provider-user/user/v1/"+id, User.class);
return entity;
}
@GetMapping("/log-instance")
public void logUserInstance(){
ServiceInstance serviceInstance = loadBalancerClient.choose("micro-provider-user");
logger.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort());
}
}
micro-provider-user 是用户微服务的虚拟主机名(virtual host name),当 Ribbon 和 Eureka 配合使用时,会自动将虚拟主机名映射成微服务的网络地址。
在默认情况下,虚拟主机名和服务名称是一致的。当然,也可使用配置属性 eureka.instance.virtual-host-name 或 eureka.instance.secure-virtual-host-name 指定虚拟主机名。
- 启动服务消费者服务 micro-consumer-movie-ribbon ,测试 Ribbon ,多次访问 http://localhost:8010/movie/v1/1 ,可发现请求会均匀分布到两个用户微服务节点上,说明已经实现了负载均衡。
访问 http://localhost:8010/movie/v1/log-instance , logUserInstance() 方法中使用 LoadBalancerClient 的 API 更加直观地获取当前选择的用户微服务节点。
使用属性自定义 Ribbon 配置
Ribbon 支持使用属性自定义,支持的属性如下:
- NFLoadBalancerClassName :配置 ILoadBalancer 的实现类
- NFLoadBalancerRuleClassName :配置 IRule 的实现类。
- NFLoadBalancerPingClassName :配置 IPing 的实现类。
- NIWSServerListClassName :配置 ServerList 的实现类。
- NIWSServerListFilterClassName :配置ServerListFilter 的实现类。
实践:通过属性来修改 Ribbon Client 的负载均衡规则。
复制项目 micro-consumer-movie-ribbon ,将 ArtifactId 修改为 micro-consumer-movie-ribbon-custom-props 。
修改 application.yml ,将名为 micro-provider-user 的 Ribbon Client 的负载均衡规则设为随机:
micro-provider-user:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
- 启动服务 micro-consumer-movie-ribbon-custom-props ,测试 http://localhost:8010/movie/v1/log-instance ,查看日志,会发现此时请求会随机分布到两个用户微服务节点上。
脱离 Eureka 使用 Ribbon
现实中某些微服务可能并没有注册到 Eureka Server 上 ,此时要想使用 Ribbon 实现负载均衡,要怎么办呢?

复制项目 micro-consumer-movie-ribbon ,将 ArtifactId 修改为 micro-consumer-movie-ribbon-without-eureka 。
删除 eureka 的依赖 spring-cloud-starter-eureka ,并为项目添加 Ribbon 依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
去掉启动类上的
@EnableDiscoveryClient注解。修改配置 application.yml ,为 micro-provider-user 设置 Ribbon 客户端设置请求的地址列表:
server:
port: 8010
spring:
application:
name: micro-consumer-movie
micro-provider-user:
ribbon:
listOfServers: localhost:8000,localhost:8001
- 启动多个服务提供者 micro-provider-user 。
java -jar micro-provider-user-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer1
java -jar micro-provider-user-0.0.1-SNAPSHOT.jar --spring.profiles.active=peer2
- 启动服务 micro-consumer-movie-ribbon-without-eureka ,测试 http://localhost:8010/movie/v1/2 或 http://localhost:8010/movie/v1/log-instance 。
由结果可知,尽管电影微服务和用户微服务此时并没有注册到 Eureka 上, Ribbon 仍可正常工作,请求依旧会分摊到两个用户微服务节点上。
饥饿加载
Spring Cloud 会为每个名称的 Ribbon Client 维护一个子应用程序上下文,这个上下文默认是懒加载的。指定名称的 Ribbon Client 第一次请求时,对应的上下文才会被加载,因此,首次请求往往会比较慢。
从 Spring Cloud Dalston 开始,我们可配置饥饿加载。例如
ribbon:
eager-load:
enabled: true
clients: client1,client2
这样,对于名为 client1 , clent2 的 Ribbon Client ,将在启动时就加载对应的子应用程序上下文,从 而提高首次请求的访问速度。
代码仓库
https://gitee.com/chentian114/spring-cloud-practice
公众号
参考
《Spring Cloud 与Docker 微服务架构实战》 周立
边栏推荐
- Use of kingbasees UDP monitoring tool for gold warehouse database
- EMC rectification cases of electronic equipment radiation
- Leetcode 1961. 检查字符串是否为数组前缀
- Wechat applet ordering system with source code
- MySQL基础篇常用约束总结下篇
- Pl/sql compilation check in kingbasees
- Common techniques for handling dates
- MySQL permission management and backup
- Where is it safer to open an account for soda ash futures? How much money can you do?
- C # introductory series (11) -- multidimensional array
猜你喜欢

Differences between beanfactorypostprocessor and beanpostprocessor

No more! The entry byte beat for a week and ran decisively.

为什么DDRx的电源设计时需要VTT电源

MySQL transaction

Mouse click coordinate transformation generation

Leetcode 1952. 三除数

电子设备辐射EMC整改案例

Ugui mouse click diffusion UI effect

Pyspark case series 4-dataframe output to a single folder solution

iPhone 15 被迫用上 Type-C 接口
随机推荐
Wsarecv: an existing connection was forcefully closed by the remote host
MD5学习
Source code of digital collection app system
金仓数据库KingbaseES中的PL/SQL 编译检查
数据库设计及范式讲解
Waiting event enq: Ko - some feasible processing methods for fast object checkpoint
NGUI,聊天滚动框,UI TextList
Xilinx pin constraint file xdc
为什么DDRx的电源设计时需要VTT电源
基于C语言实现比赛评分系统
MySQL基础篇常用约束总结上篇
GameFi:您需要了解的关于“即玩即赚”游戏经济的一切
Circuit board made of real gold -- golden finger
MySQL基础篇常用约束总结下篇
RSA signature issues
安全相关网站推荐
NFT将改变元宇宙中的数据所有权
利用PHP开发的一款万能、表白墙系统部分代码片段
TikTok在英国遭遇文化冲突,短期内众多员工离职
【DBSCAN】DBSCAN实例