SpringCloudAlibaba - 整合 Ribbon 实现负载均衡
目录
前言
Ribbon是一个Netflix开源的客户端侧负载均衡器,其提供了丰富的负载均衡算法,服务消费者集成Ribbon后,Ribbon会自动从Nacos Server获取想要调用的服务的地址列表,通过负载均衡算法计算出一个实例交给RestTemplate调用
注:Spring Cloud 2020 已移除对 Ribbon 的支持,相应的,Spring Cloud 2021 版本 Nacos 中 也删除了Ribbon 的 jar 包,实现时需要注意版本依赖关系
环境
Spring Cloud Hoxton.SR9 + Spring Cloud Alibaba 2.2.6.RELEASE
简单示例
spring-cloud-starter-alibaba-nacos-discovery中默认包含Ribbon,所以不需要添加依赖

这里的示例代码是内容中心(content-center)通过调用用户中心(user-center)的两个实例看是否实现负载均衡
user-center
TestController.java
@RestController
@Slf4j
public class TestController {
@GetMapping("/test/{name}")
public String test(@PathVariable String name) {
log.info("请求...");
return "hello " + name;
}
}
- 用户中心以
8081,8082端口启动


content-center
- 启动类
/**
* @LoadBalanced 为RestTemplate 整合Ribbon
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
TestController.java
@RestController
@Slf4j
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class TestController {
private final RestTemplate restTemplate;
/**
* 整合Ribbon
* @return
*/
@GetMapping("test3")
public String test3() {
/**
* RestTemplate 请求时,ribbon会把user-center转换成用户中心在Nacos上的地址,
* 进行负载均衡算法计算出一个实例去请求
*/
return restTemplate.getForObject(
"http://user-center/test/{name}",
String.class,
"Coisini"
);
}
}
测试
- 访问接口测试,可以发现
Ribbon以轮询的方式实现负载均衡


Ribbon 的组成和默认的负载均衡规则
Ribbon 的组成
Ribbon为所有的组件提供了接口,如果对默认值不满意,可以实现这些接口进行二次开发
| 接口 | 作用 | 默认值 |
|---|---|---|
| IClientConfig | 读取配置 | DefaultClientConfigImpl |
| IRule | 负载均衡规则,选择实例 | ZoneAvoidanceRule |
| IPing | 筛选掉ping不通的实例 | DummyPing |
| ServerList< Server> | 交给Ribbon的实例列表 | Ribbon:ConfigurationBasedServerList Spring Cloud Alibaba: NacosServerList |
| ServerListFilter< Server> | 过滤掉不符合条件的实例 | ZonePreferenceServerListFilter |
| ILoadBalancer | Ribbon的入口 | ZoneAwareLoadBalancer |
| ServerListUpdater | 更新交给Ribbon的List的策略 | PollingServerListUpdater |
Ribbon 默认的负载均衡规则
Ribbon默认的负载均衡规则是ZoneAvoidanceRule,在没有zone的情况下默认是轮询Ribbon内置的负载均衡规则如下
| 规则名称 | 特点 |
|---|---|
| AvailabilityFilteringRule | 过滤掉一直连接失败的被标记为circuit tripped的后端Server,并过滤掉那些高并发的后端Server或者使用一个AvailabilityPredicate来包含过滤server的逻辑,其实就是检查status里记录的各个Server的运行状态 |
| BestAvailableRule | 选择一个最小的并发请求的Server,逐个考察Server,如果Server被tripped了,则跳过 |
| RandomRule | 随机选择一个Server |
| ResponseTimeWeightedRule | 已废弃,作用同WeightedResponseTimeRule |
| RetryRule | 对选定的负载均衡策略机上重试机制,在同一个配置时间段内当选择Server不成功,则一直尝试使用subRule的方式选择一个可用的Server |
| RoundRobinRule | 轮询选择,轮询index,选择index对应位置的Server |
| WeightedResponseTimeRule | 根据响应时间加权,响应时间越长,权重越小,被选中的可能性越低 |
| ZoneAvoidanceRule | 复合判断Server所在Zone的性能和Server的可用性选择Server,在没有Zone的环境下,类似于轮询(RoundRobinRule) |
Ribbon 的自定义配置
实现目的:通过自定义配置实现随机选择
Java 代码配置方式
UserCenterRibbonConfiguration.java
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.context.annotation.Configuration;
import ribbonconfiguration.RibbonConfiguration;
/**
* @Description 用户中心配置类
*/
@Configuration
@RibbonClient(name = "user-center", configuration = RibbonConfiguration.class)
public class UserCenterRibbonConfiguration {
}
RibbonConfiguration.java
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description Ribbon的配置类
* Ribbon的配置类要有@Configuration注解,但不能被@ComponentScan重复扫描
* 否则就会被所有的RibbonClient共享
*/
@Configuration
public class RibbonConfiguration {
/**
* 自定义负载均衡规则
* RandomRule 随机选择
* @return
*/
@Bean
public IRule ribbonRule() {
return new RandomRule();
}
}
- 目录结构如下所示,
Ribbon配置类RibbonConfiguration.java位置在java目录下,其作用是避免父子上下文重叠,Ribbon的配置类要有@Configuration注解,但不能被@ComponentScan重复扫描,否则就会被所有的RibbonClient共享

- 接口访问测试发现随机访问已实现


yml 属性配置方式
- 注释
Java代码配置方式中的代码,在application.yml中添加user-center的负载均衡规则,也能实现相同的效果
user-center:
ribbon:
# Ribbon负载均衡规则的全路径
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule
Ribbon 的全局配置
- 有自定义配置就有全局配置,可以通过修改
@RibbonClient注解为@RibbonClients注解实现全局配置 UserCenterRibbonConfiguration.java
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.context.annotation.Configuration;
import ribbonconfiguration.RibbonConfiguration;
/**
* @Description 用户中心配置类
*/
@Configuration
@RibbonClients(defaultConfiguration = RibbonConfiguration.class)
public class UserCenterRibbonConfiguration {
}
RibbonConfiguration.java
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @Description Ribbon的配置类
*/
@Configuration
public class RibbonConfiguration {
/**
* 自定义负载均衡规则
* RandomRule 随机选择
* @return
*/
@Bean
public IRule ribbonRule() {
return new RandomRule();
}
}
Ribbon 的饥饿加载
-
默认情况下
Ribbon是懒加载的,当RestTemplate第一次调用RibbonClient时才会创建一个client,这样会导致首次请求过慢或失败的问题,可以通过属性配置开启Ribbon的饥饿加载 -
application.yml
ribbon:
eager-load:
# 开启饥饿加载
enabled: true
# 为哪些RibbonClient开启饥饿加载,多个用 "," 隔开
clients: user-center
项目源码
GitHub: https://github.com/Maggieq8324/coisini-cloud-alibabaGitee: https://gitee.com/maggieq8324/coisini-cloud-alibaba

浙公网安备 33010602011771号