微服务 客户端负载均衡
Spring Cloud LoadBalancer是Spring Cloud官方提供的客户端负载均衡工具,是Netflix Ribbon的官方替代方案。
1 客户端负载均衡概述
服务端负载均衡与客户端负载均衡:
负载均衡分为通常指服务端负载均衡,分为硬件负载均衡和软件负载均衡。二者都会下挂可用服务端清单,通过心跳检测来剔除有故障的服务节点以保持清单中都是可以正常访问的服务端节点。 当客户端发送请求到负载均衡设备时。设备按照算法(线性轮询、按权重负载、按流量负载等)从可用的服务端清单中取出一台服务端地址,进行请求转发。 客户端负载均衡和服务端负载均衡的最大的不同在于服务清单的存储位置。客户端负载均衡中所有客户端节点都会维护自己要访问的服务端清单(来自服务注册中心)。客户端负载均衡也需要心跳去维护服务端清单的健康性,这个步骤需要服务注册中心配合完成。
负载均衡作用:
- 系统高可用
- 缓解网络压力
- 处理能力扩容
使用方法:
- 服务提供者启动多个服务实例并注册到注册中心。
- 服务消费者直接通过调用被
@LoadBalanced注解修饰过的RestTemplate来实现面向服务的接口调用。
2 RestTemplate集成
Spring Cloud LoadBalancer可以与RestTemplate无缝集成,支持各种HTTP请求类型。
2.1 引入依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>2.2 配置RestTemplate
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}2.3 HTTP请求类型
2.3.1 GET请求
可以通过两种方法实现。
- 使用
getForEntity方法返回ResponseEntity,该对象是spring对Http请求响应的封装。 - 使用
getForObject该方法将http响应中的body内容转换为对象。
2.3.2 POST请求
- 使用
postForEntity - 使用
postForObject - 使用
postForLocation,返回资源的URI
这里新增加了Object request 参数,该参数可以是一个普通对象,也可以是一个HttpEntity,后者会被当成HTTP请求对象处理。
2.3.3 PUT请求
使用put
2.3.4 DELETE
使用delete
3 负载均衡策略
Spring Cloud LoadBalancer提供了多种负载均衡策略:
3.1 RoundRobinLoadBalancer(默认)
线性轮询策略,依次请求可用服务实例。
3.2 RandomLoadBalancer
随机选择可用服务实例。
3.3 WeightedLoadBalancer
基于权重的负载均衡策略(需要额外配置)。
3.4 自定义负载均衡策略
可以通过实现ReactorServiceInstanceLoadBalancer接口来自定义负载均衡策略。
4 参数配置
Spring Cloud LoadBalancer的配置主要通过spring.cloud.loadbalancer前缀进行:
4.1 全局配置
spring:
cloud:
loadbalancer:
# 启用重试机制
retry:
enabled: true
# 禁用缓存
cache:
enabled: false
# 配置客户端超时
client:
config:
default:
connectTimeout: 250
readTimeout: 10004.2 针对特定服务的配置
spring:
cloud:
loadbalancer:
client:
config:
bookservice:
connectTimeout: 500
readTimeout: 20005 重试机制
Spring Cloud LoadBalancer内置了重试机制,可以与Spring Retry结合使用:
5.1 引入依赖
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>5.2 配置重试
spring:
application:
name: customerclient
cloud:
loadbalancer:
retry:
enabled: true
max-retries-on-same-service-instance: 1
max-retries-on-next-service-instance: 2
# 配置Resilience4J超时(替代Hystrix)
resilience4j:
timelimiter:
instances:
default:
timeoutDuration: 10s5.3 重试规则
max-retries-on-same-service-instance: 对同一服务实例的最大重试次数max-retries-on-next-service-instance: 切换到下一个服务实例的最大重试次数- 重试机制会自动跳过不健康的服务实例
6 WebClient集成
除了RestTemplate,Spring Cloud LoadBalancer还支持与WebClient集成:
@Configuration
public class WebClientConfig {
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
@Bean
public WebClient webClient(WebClient.Builder builder) {
return builder.build();
}
}7 Ribbon迁移注意事项
- 依赖替换:移除
spring-cloud-starter-netflix-ribbon,添加spring-cloud-starter-loadbalancer - 配置变更:将
ribbon.*配置迁移到spring.cloud.loadbalancer.* - 重试机制:使用Spring Cloud LoadBalancer内置重试或结合Spring Retry
- 自定义策略:实现
ReactorServiceInstanceLoadBalancer接口替代Ribbon的IRule
8 常见问题
8.1 负载均衡不生效
检查是否:
- 添加了
@LoadBalanced注解 - 引入了正确的依赖
- 服务名称配置正确
8.2 重试机制不工作
确保:
- 启用了重试功能
- 引入了Spring Retry依赖
- 超时设置合理
总结
Spring Cloud LoadBalancer作为Ribbon的官方替代方案,提供了更现代、更灵活的客户端负载均衡功能。它与Spring Cloud生态系统无缝集成,支持RestTemplate和WebClient,提供了丰富的负载均衡策略和配置选项。