SpringCloud-Alibaba学习(四):Ribbon负载均衡

Ribbon负载均衡

1、简介

Ribbon 是 Netflix 公司开源的一个负载均衡的项目,是客户端负载均衡器,运行在客户端上。
用于解决服务实例列表在调用时的负载均衡的问题。

2、Ribbon 使用

前篇 nacos 实例中有相关集成:https://www.cnblogs.com/liuyiyuan/p/16421731.html#325-远程调用

第一步:pom 依赖
SpringCloud 已经依赖了 Ribbon

第二步:@LoadBalance 注解
通过 Spring Cloud 原生注解 @EnableDiscoveryClient 开启服务注册发现,再给RestTemplate 实例添加 @LoadBalance 注解,开启与 Ribbon 的集成,代码中无感知。

@Bean
@LoadBalanced // 使Ribbon生效
public RestTemplate restTemplate() {
return new RestTemplate();
}

3、Ribbon 工作流程

4、Ribbon 源码了解

LoadBalancerAutoConfiguration 自动注入拦截器

进入 LoadBalancerInterceptor

@Override
public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
final ClientHttpRequestExecution execution) throws IOException {
final URI originalUri = request.getURI(); // 从请求中获取 URI
String serviceName = originalUri.getHost(); // 获取 host 作为服务名
Assert.state(serviceName != null,
"Request URI does not contain a valid hostname: " + originalUri);
return this.loadBalancer.execute(serviceName,
this.requestFactory.createRequest(request, body, execution));
}

查看 this.loadBalancer.execute 方法
会进入 RibbonLoadBalancerClient#execute 方法

public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
throws IOException {
ILoadBalancer loadBalancer = getLoadBalancer(serviceId); // 获取实例列表,serviceId就是服务名
Server server = getServer(loadBalancer, hint); // 对实例列表进行负载均衡获取到一个server
if (server == null) {
throw new IllegalStateException("No instances available for " + serviceId);
}
RibbonServer ribbonServer = new RibbonServer(serviceId, server,
isSecure(server, serviceId),
serverIntrospector(serviceId).getMetadata(server));
return execute(serviceId, ribbonServer, request);
}

方法 getLoadBalancer(serviceId) 会创建负载均衡器 ZoneAwareLoadBalancer

方法 getServer(loadBalancer, hint) 内部调用 ZoneAwareLoadBalancer#chooseServer,再调用父类方法即BaseLoadBalancer#chooseServer,根据负载均衡策略获取具体的 Server

5、Ribbon 的负载均衡策略

Ribbon 的负载均衡策略核心组件是 IRule,根据特定算法从服务列表中选取一个需要访问的服务;
其中 IRule 是一个接口,有七个自带的实现,可以实现不同的负载均衡策略

策略类 策略描述
BestAvailableRule 选择并发请求最少的server
AvailabilityFilteringRule 先过滤掉由于多次访问故障而处于断路器跳闸状态的服务,以及并发连接数超过阈值的服务,然后对剩余服务进行轮询
WeightedResponseTimeRule 根据平均响应时间计算服务权重,若统计信息不足则安装轮询规则,统计信息足够后按照响应时间选择服务
RetryRule 正常时按照轮询选择服务,有服务出现故障时,在轮询一定次数后依然故障,则会跳过故障的服务继续轮询
RoundRobinRule 轮询规则
RandomRule 随机规则
ZoneAvoidanceRule 默认策略,加了一些过滤条件,过滤成功后继续采用轮询方式选择服务

切换 Ribbon 默认的负载均衡策略

Ribbon 是客户端的负载均衡器,所以策略要配置到服务消费方上。

配置类,注意这个配置类不需要 Spring 的扫描自动注入

public class RibbonRuleConfig {
@Bean
public IRule rule() {
return new RandomRule();
}
}

启动类上添加注解,指定上面的配置类

// name为要调的微服务名称,configuration指定策略配置类
@RibbonClient(name = "ribbon-provider", configuration = RibbonRuleConfig.class)

6、缓存的定时刷新

服务消费方在第一次远程调用时,会将服务信息缓存起来,后续直接通过缓存发起调用。

如果注册中心的服务列表发生了变更,消费方如何感知呢?

ribbon 是使用了定时刷新机制。

核心代码在类 DynamicServerListLoadBalancer中的ServerListUpdater.UpdateAction#doUpdate


定时调度是 PollingServerListUpdater#start 方法内定义了一个 Runnable 使用 ScheduledThreadPoolExecutor 进行调度,调度时间间隔是 30s

posted @   originyuan  阅读(275)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· 单线程的Redis速度为什么快?
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
点击右上角即可分享
微信分享提示