负载均衡
# LoadBalancer
LoadBalancer 是 SpringCloud 官方提供的负载均衡组件
Maven依赖
<!-- loadbalancer -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
配置文件
spring:
cloud:
loadbalancer:
cache: # 服务列表的缓存配置
enable: true # 是否启用缓存,默认开启
ttl: 35s # 缓存过期时间,默认35s
capacity: 1024 # 设置缓存个数,默认256个
retry: # 请求失败的重试策略
enabled: true # 是否启用重试,默认启用
avoid-previous-instance: true # 是否在重试时避免失败的服务实例,默认启用
max-retries-on-same-service-instance: 0 # 当前服务实例的最大重试次数
max-retries-on-next-service-instance: 1 # 下一个服务实例的最大重试次数
backoff: # 重试退避策略:当一个请求失败时,下一次重试应该等待多长时间
enabled: false # 是否启用重试退避策略,默认不启用
min-backoff: 5ms # 规避最短时间
max-backoff: 5000ms # 规避最长时间
# 负载均衡策略
LoadBalancer 中可以通过ReactorLoadBalancer
接口的实现类来查看内置了哪些负载均衡器,通过效仿他们的写法可以实现自定义负载均衡器
实现类 | 作用 |
---|---|
RandomLoadBalancer | 随机分配 |
RoundRobinLoadBalancer | 默认策略 轮询 |
想要修改或自定义轮询策略需要编写配置类使用@Bean
提供负载均衡器对象
// 这里不需要使用@Configuration之类的注解!!
public class LoadBalanceConfig {
@Bean
public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
单独配置轮询策略
在想要配置轮询策略的 Feign 上使用@LoadBalancerClient
注解,仅对当前 Feign 生效
@LoadBalancerClient(configuration = LoadBalanceConfig.class)
@FeignClient(value = "shop-order", path = "/order")
public interface ShopOrderFeign { ... }
全局配置轮询策略
在启动类上使用@LoadBalancerClients
注解,可以对所有远程调用生效
@EnableDiscoveryClient
@LoadBalancerClients(defaultConfiguration = LoadBalanceConfig.class)
@MapperScan("site.hanzhe.practice.sys.mapper")
@EnableFeignClients(basePackages = "site.hanzhe.practice.api")
@SpringBootApplication(scanBasePackages = "site.hanzhe.practice")
public class PracticeSysApp { ... }
Nacos提供的负载均衡器
Nacos 中提供了 LoadBalancer 的负载均衡器,支持权重负载均衡和地域就近访问两种策略,默认使用权重负载均衡策略,可以在 Nacos 中点进服务详情下滑到集群位置,为每个服务设置权重,如果服务注册时设置了集群信息会优先调用同集群下的服务
@Bean
public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory, NacosDiscoveryProperties nacosDiscoveryProperties) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
new NacosLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name, nacosDiscoveryProperties);
return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
# Ribbon
负载均衡组件,项目中获取到服务地址列表后就会交给 Ribbon 进行负载均衡
配置文件
ribbon:
eager-load: # 启用clients服务的饥饿加载,提高首次执行效率
enable: true
clients: 服务名
服务名称:
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 配置该服务的负载均衡策略
# 负载均衡策略
Ribbon 底层有个 IRule 接口,代表负载均衡规则,可以创建类实现该接口自定义规则,常用的内置规则如下:
实现类 | 作用 |
---|---|
RandomRule | 随机分配 |
RoundRobinRule | 轮询策略 |
ZoneAvoidanceRule | 默认策略,区域性的负载均衡 |
ClientConfigEnableRoundRobinRule | 支持自定义配置的轮询策略 |
BestAvailableRule | 选择连接数最少的服务 |
ShortestResponseTimeRule | 总是将请求分给响应最快的服务 |
WeightedResponseTimeRule | 根据服器响应时间分配权重,根据权重分配请求 |
修改默认负载均衡策略的方法:
- 创建 IRule 接口的实现类对象,添加到 IOC 容器中实现全局使用
- 在配置文件中针对某个服务名设置负载均衡策略,优先级高于全局