Spring Cloud Ribbon是Netflix开源客户端负载均衡器,旨在为微服务架构提供一种简单而有效的负载均衡解决方案。支持多种负载均衡策略,如轮询、随机、最少活跃调用等,能够无缝集成Spring Cloud组件。
01 负载均衡方式
1.1 服务器负载均衡
在服务器端部署专门负载均衡设备或者软件,按照一定算法和规则转发客户端发送请求,分配到多个后端服务器进行处理,以此实现服务器资源合理利用和系统高可用性。
1.2 客户端负载均衡
客户端集成负载均衡功能到应用程序,客户端根据服务注册中心注册表,自行运用负载均衡算法选择要访问的服务器,从而将请求分配到不同服务器上,达到负载均衡的目的。
02 手写客户端负载均衡器
public class OrderController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("/order/create")
public String createOrder(Integer productId) {
List<ServiceInstance> instances = discoveryClient.getInstances("stock");
List<String> targetUrls = instances.stream()
// 数据变换
.map(instance -> instance.getUri().toString() + "/stock/reduce")
.collect(Collectors.toList());
int i = ThreadLocalRandom.current().nextInt(targetUrls.size());
String targetUrl = targetUrls.get(i);
log.info("request target url = {}", targetUrl);
String result = restTemplate.getForObject(targetUrl + "/" + productId, String.class);
log.info("Reduce stock result = {}", result);
return "ok";
}
}
03 Ribbon实现负载均衡
Ribbon是Netflix开源客户端负载均衡器,扩展RestTemplate提供多种负载均衡算法,实现客户端负载均衡请求路由。
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR9</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
public class OrderController {
@Autowired
@LoadBalanced
private RestTemplate restTemplate;
@GetMapping("/order/create")
public String createOrder(Integer productId) {
String result = restTemplate.getForObject("http://stock/stock/reduce" + productId, String.class);
log.info("Reduce stock result = {}", result);
return "ok";
}
}
04 Ribbon重要组件
4.1 Ribbon接口定义
| 接口 | 作用 | 默认值 |
|---|---|---|
| IClientConfig | 读取配置 | DefaultclientConfigImpl |
| IRule | 负载均衡规则 | ZoneAvoidanceRule |
| IPing | 剔除Ping不通实例 | 默认值为DummyPing实例,不检查也不剔除实例 |
| ServerList<Server> | Ribbon实例列表 | Ribbon: ConfigurationBasedServerList Spring Cloud Alibaba: NacosServerList |
| ServerListFilter | 剔除不符合条件的实例 | ZonePreferenceServerListFilter |
| ILoadBalancer | Ribbon入口 | ZoneAwareLoadBalancer |
| ServerListUpdater | 更新Ribbon策略 | PollingServerListUpdater |
4.2 Ribbon负载均衡规则
| 规则名称 | 特点 |
|---|---|
| RandomRule | 随机选择Server |
| RetryRule | 选定负载均衡策略添加重试机制,选择可用实例进行重试 |
| RoundRobinRule | 轮询选择 |
| WeightedResponseTimeRule | 响应时间加权机制,响应时间越长权重越小,被选中可能性越低 |
| ZoneAvoidanceRule | (默认)最佳区域访问策略。没有Zone环境类似轮询策略 |
05 Ribbon配置
Ribbon支持三种配置方式,分别是类配置、属性配置和全局配置,优先级按照顺序依次递减。
5.1 类配置方式
public class RibbonConfiguration {
@Bean
public IRule ribbonRule(){
// 随机策略
return new RandomRule();
}
}
@Configuration
@RibbonClient(name = "stock",configuration = RibbonConfiguration.class)
public class UserRibbonConfiguration {
}
5.2 属性配置方式
stock:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 负载均衡规则
ConnectTimeout: 5000 # 连接超时时间(毫秒)
ReadTimeout: 6000 # 读取超时时间(毫秒)
MaxAutoRetries: 1 # 同一实例的重试次数
MaxAutoRetriesNextServer: 2 # 切换实例的重试次数
OkToRetryOnAllOperations: true # 是否对所有操作进行重试
5.4 全局配置
@Configuration
@RibbonClient(defaultConfiguration = RibbonConfiguration.class)
public class UserRibbonConfiguration {
}
06 饥饿加载
Ribbon默认配置为懒加载模式,只有第一次调用才会生成提供者RibbonClient,从而导致首次调用很慢。
ribbon:
eager-load:
enabled: true
clients: stock