负载均衡 #
一、负载均衡概述 #
1.1 什么是负载均衡 #
负载均衡是将请求分发到多个服务实例的机制,提高系统的吞吐量和可用性。
text
┌─────────────────────────────────────────────────────────────┐
│ 负载均衡架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ │
│ │ 客户端 │ │
│ └──────┬──────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ 负载均衡器 │ │
│ │ │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ Round │ │ Random │ │ Weighted│ │ │
│ │ │ Robin │ │ │ │ │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ├──────────────────┬──────────────────┐ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ 实例 1 │ │ 实例 2 │ │ 实例 3 │ │
│ │ :8001 │ │ :8002 │ │ :8003 │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
1.2 负载均衡分类 #
| 类型 | 说明 | 典型实现 |
|---|---|---|
| 服务端负载均衡 | 独立的负载均衡服务器 | Nginx、F5、HAProxy |
| 客户端负载均衡 | 客户端内置负载均衡 | Ribbon、LoadBalancer |
1.3 LoadBalancer vs Ribbon #
| 特性 | LoadBalancer | Ribbon |
|---|---|---|
| 维护状态 | 活跃 | 维护模式 |
| 响应式 | 支持 | 不支持 |
| 缓存 | 支持 | 不支持 |
| 健康检查 | 支持 | 支持 |
二、基本使用 #
2.1 添加依赖 #
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
2.2 RestTemplate集成 #
java
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2.3 使用RestTemplate #
java
@Service
public class UserService {
@Autowired
private RestTemplate restTemplate;
public User getUser(Long id) {
String url = "http://user-service/users/" + id;
return restTemplate.getForObject(url, User.class);
}
}
2.4 WebClient集成 #
xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
java
@Configuration
public class WebClientConfig {
@Bean
@LoadBalanced
public WebClient.Builder webClientBuilder() {
return WebClient.builder();
}
}
java
@Service
public class UserService {
@Autowired
private WebClient.Builder webClientBuilder;
public Mono<User> getUser(Long id) {
return webClientBuilder.build()
.get()
.uri("http://user-service/users/{id}", id)
.retrieve()
.bodyToMono(User.class);
}
}
三、负载均衡策略 #
3.1 内置策略 #
| 策略 | 类名 | 说明 |
|---|---|---|
| 轮询 | RoundRobinLoadBalancer | 按顺序选择(默认) |
| 随机 | RandomLoadBalancer | 随机选择 |
3.2 配置轮询策略(默认) #
yaml
spring:
cloud:
loadbalancer:
ribbon:
enabled: false
3.3 配置随机策略 #
java
@Configuration
public class LoadBalancerConfig {
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
Environment environment,
LoadBalancerClientFactory factory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(
factory.getLazyProvider(name, ServiceInstanceListSupplier.class),
name
);
}
}
3.4 自定义负载均衡策略 #
java
public class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private final String serviceId;
private final ServiceInstanceListSupplier serviceInstanceListSupplier;
public CustomLoadBalancer(String serviceId, ServiceInstanceListSupplier supplier) {
this.serviceId = serviceId;
this.serviceInstanceListSupplier = supplier;
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
return serviceInstanceListSupplier.get()
.next()
.map(instances -> {
if (instances.isEmpty()) {
return new EmptyResponse();
}
ServiceInstance instance = selectInstance(instances);
return new DefaultResponse(instance);
});
}
private ServiceInstance selectInstance(List<ServiceInstance> instances) {
return instances.get(0);
}
}
java
@Configuration
public class LoadBalancerConfig {
@Bean
public ReactorLoadBalancer<ServiceInstance> customLoadBalancer(
Environment environment,
LoadBalancerClientFactory factory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new CustomLoadBalancer(name,
factory.getLazyProvider(name, ServiceInstanceListSupplier.class));
}
}
四、服务实例选择器 #
4.1 自定义ServiceInstanceListSupplier #
java
public class CustomServiceInstanceListSupplier
extends DelegatingServiceInstanceListSupplier {
public CustomServiceInstanceListSupplier(ServiceInstanceListSupplier delegate) {
super(delegate);
}
@Override
public Flux<List<ServiceInstance>> get() {
return delegate.get()
.map(instances -> {
return instances.stream()
.filter(this::isHealthy)
.collect(Collectors.toList());
});
}
private boolean isHealthy(ServiceInstance instance) {
Map<String, String> metadata = instance.getMetadata();
String status = metadata.get("status");
return "UP".equals(status);
}
}
java
@Configuration
public class LoadBalancerConfig {
@Bean
public ServiceInstanceListSupplier serviceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHealthChecks()
.build(context);
}
}
五、健康检查 #
5.1 开启健康检查 #
yaml
spring:
cloud:
loadbalancer:
health-check:
enabled: true
initial-delay: 0
interval: 25s
path:
default: /actuator/health
5.2 配置健康检查 #
java
@Configuration
public class LoadBalancerConfig {
@Bean
public ServiceInstanceListSupplier healthCheckServiceInstanceListSupplier(
ConfigurableApplicationContext context) {
return ServiceInstanceListSupplier.builder()
.withDiscoveryClient()
.withHealthChecks()
.build(context);
}
}
六、缓存配置 #
6.1 开启缓存 #
yaml
spring:
cloud:
loadbalancer:
cache:
enabled: true
ttl: 35s
capacity: 256
6.2 自定义缓存 #
java
@Configuration
public class LoadBalancerConfig {
@Bean
public LoadBalancerCacheFactory loadBalancerCacheFactory() {
return new DefaultLoadBalancerCacheFactory(256, 35, true);
}
}
七、重试机制 #
7.1 添加依赖 #
xml
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
7.2 配置重试 #
yaml
spring:
cloud:
loadbalancer:
retry:
enabled: true
retry-on-all-operations: false
max-retries-on-next-service-instance: 1
max-retries-on-same-service-instance: 0
7.3 自定义重试策略 #
java
@Configuration
public class RetryConfig {
@Bean
public LoadBalancedRetryFactory loadBalancedRetryFactory() {
return new LoadBalancedRetryFactory() {
@Override
public RetryPolicy createRetryPolicy(String service, ServiceInstanceListSupplier serviceInstanceListSupplier) {
return new SimpleRetryPolicy(3);
}
};
}
}
八、提示机制 #
8.1 开启提示 #
yaml
spring:
cloud:
loadbalancer:
hint:
enabled: true
8.2 使用提示 #
java
@RestController
public class UserController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/users/{id}")
public User getUser(@PathVariable Long id) {
RequestData requestData = new RequestData(
"GET",
URI.create("http://user-service/users/" + id),
new HttpHeaders(),
null,
new HashMap<>()
);
requestData.getHints().put("zone", "zone-1");
return restTemplate.exchange(
requestData.getRequest(),
User.class
).getBody();
}
}
九、配置详解 #
9.1 完整配置 #
yaml
spring:
cloud:
loadbalancer:
enabled: true
ribbon:
enabled: false
cache:
enabled: true
ttl: 35s
capacity: 256
health-check:
enabled: true
initial-delay: 0
interval: 25s
path:
default: /actuator/health
user-service: /health
retry:
enabled: true
retry-on-all-operations: false
max-retries-on-next-service-instance: 1
max-retries-on-same-service-instance: 0
hint:
enabled: true
zone: default
9.2 配置项说明 #
| 配置项 | 默认值 | 说明 |
|---|---|---|
| enabled | true | 是否启用负载均衡 |
| cache.enabled | true | 是否启用缓存 |
| cache.ttl | 35s | 缓存过期时间 |
| health-check.enabled | false | 是否启用健康检查 |
| retry.enabled | true | 是否启用重试 |
十、加权负载均衡 #
10.1 基于元数据的权重 #
yaml
eureka:
instance:
metadata-map:
weight: 100
10.2 自定义加权负载均衡 #
java
public class WeightedLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private final String serviceId;
private final ServiceInstanceListSupplier serviceInstanceListSupplier;
private final Random random = new Random();
public WeightedLoadBalancer(String serviceId, ServiceInstanceListSupplier supplier) {
this.serviceId = serviceId;
this.serviceInstanceListSupplier = supplier;
}
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
return serviceInstanceListSupplier.get()
.next()
.map(instances -> {
if (instances.isEmpty()) {
return new EmptyResponse();
}
ServiceInstance instance = selectByWeight(instances);
return new DefaultResponse(instance);
});
}
private ServiceInstance selectByWeight(List<ServiceInstance> instances) {
int totalWeight = instances.stream()
.mapToInt(this::getWeight)
.sum();
int randomWeight = random.nextInt(totalWeight);
int currentWeight = 0;
for (ServiceInstance instance : instances) {
currentWeight += getWeight(instance);
if (randomWeight < currentWeight) {
return instance;
}
}
return instances.get(0);
}
private int getWeight(ServiceInstance instance) {
String weight = instance.getMetadata().get("weight");
return weight != null ? Integer.parseInt(weight) : 1;
}
}
十一、最佳实践 #
11.1 生产环境配置 #
yaml
spring:
cloud:
loadbalancer:
enabled: true
ribbon:
enabled: false
cache:
enabled: true
ttl: 30s
capacity: 512
health-check:
enabled: true
initial-delay: 10s
interval: 30s
retry:
enabled: true
max-retries-on-next-service-instance: 2
11.2 注意事项 #
| 注意点 | 说明 |
|---|---|
| 缓存配置 | 合理设置缓存时间和容量 |
| 健康检查 | 生产环境建议开启 |
| 重试策略 | 避免无限重试 |
| 超时配置 | 与服务调用超时配合 |
十二、总结 #
12.1 核心要点 #
| 要点 | 说明 |
|---|---|
| 客户端负载均衡 | LoadBalancer替代Ribbon |
| 负载均衡策略 | 轮询、随机、自定义 |
| 健康检查 | 自动剔除不健康实例 |
| 缓存机制 | 提高服务发现性能 |
| 重试机制 | 提高调用成功率 |
12.2 下一步 #
现在你已经掌握了负载均衡的使用,接下来让我们学习 服务网关,了解Spring Cloud Gateway的核心功能!
最后更新:2026-03-28