以下是针对 Spring Cloud Gateway 配置具体负载均衡策略(如加权轮询、最小连接数等)的详细指南,结合最新技术文档和最佳实践:
一、基础配置与依赖
1. 引入依赖
确保项目中已包含 Spring Cloud Gateway 和负载均衡器(Spring Cloud LoadBalancer)的依赖:
xml
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
若需集成服务发现(如 Nacos/Eureka),还需添加对应依赖 。
2. 启用负载均衡
在路由配置中使用 lb://service-id
格式的 URI,Gateway 会自动启用负载均衡:
yaml
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service # 启用负载均衡
predicates:
- Path=/api/user/**
二、配置内置负载均衡策略
Spring Cloud LoadBalancer 默认支持以下策略,可通过配置或代码自定义:
1. 轮询策略(默认)
无需额外配置,默认按顺序分配请求到服务实例 。
2. 加权轮询
通过服务实例的元数据(Metadata)设置权重,动态调整流量分配:
-
步骤1:在服务注册时添加权重元数据(以 Nacos 为例):
yamlspring: cloud: nacos: discovery: metadata: weight: "3" # 权重值(数值越大分配流量越多)
-
步骤2:在 Gateway 中配置加权响应时间策略:
typescript@Configuration public class WeightedLoadBalancerConfig { @Bean public ReactorLoadBalancer<ServiceInstance> weightedLoadBalancer( Environment env, LoadBalancerClientFactory factory) { String serviceId = env.getProperty("loadbalancer.client.name"); return new WeightedResponseTimeLoadBalancer( factory.getLazyProvider(serviceId, ServiceInstanceListSupplier.class), serviceId); } }
需配合
@LoadBalancerClient(name = "user-service", configuration = WeightedLoadBalancerConfig.class)
注解使用 。
3. 随机策略
自定义随机选择实例的负载均衡器:
typescript
@Bean
public ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(
Environment env, LoadBalancerClientFactory factory) {
String serviceId = env.getProperty("loadbalancer.client.name");
return new RandomLoadBalancer(
factory.getLazyProvider(serviceId, ServiceInstanceListSupplier.class),
serviceId);
}
注册方式同加权轮询 。
三、高级自定义策略
1. 最小连接数策略
需自行实现 ReactorServiceInstanceLoadBalancer
接口,通过监控实例活跃请求数选择负载最低的实例:
scss
public class LeastConnectionsLoadBalancer implements ReactorServiceInstanceLoadBalancer {
private final ConcurrentHashMap<String, AtomicInteger> connectionCounts = new ConcurrentHashMap<>();
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
return supplier.get().next().map(instances -> {
ServiceInstance selected = instances.stream()
.min(Comparator.comparingInt(instance ->
connectionCounts.getOrDefault(instance.getInstanceId(), new AtomicInteger(0)).get()))
.orElseThrow();
connectionCounts.computeIfAbsent(selected.getInstanceId(), k -> new AtomicInteger(0)).incrementAndGet();
return new Response<>(selected);
});
}
}
注册为 Bean 后通过 @LoadBalancerClient
指定服务 。
2. 一致性哈希策略
适用于需要会话粘性(Sticky Session)的场景:
vbscript
public class HashLoadBalancer implements ReactorServiceInstanceLoadBalancer {
@Override
public Mono<Response<ServiceInstance>> choose(Request request) {
String clientIp = request.getHeaders().getFirst("X-Forwarded-For");
int hash = Objects.hashCode(clientIp);
return supplier.get().next().map(instances -> {
int index = hash % instances.size();
return new Response<>(instances.get(Math.abs(index)));
});
}
}
通过请求头或客户端 IP 哈希固定路由到同一实例 。
四、动态策略调整与监控
1. 结合配置中心
通过 Nacos/Apollo 动态更新负载均衡策略参数(如权重),无需重启服务 。
2. 监控与调试
-
启用 Actuator 端点:
yamlmanagement: endpoints: web: exposure: include: gateway,loadbalancer
访问
/actuator/loadbalancer/stats
查看负载均衡统计信息 。 -
Prometheus 集成:监控各实例的请求分布和性能指标 。
五、生产建议
-
策略选择:
- 加权轮询:适合实例性能差异明显的场景(如混合部署新旧硬件)。
- 最小连接数:适用于长连接或处理耗时差异大的服务(如文件上传)。
- 一致性哈希:需要会话保持的遗留系统迁移 。
-
性能优化:避免在自定义策略中嵌入复杂计算,优先使用内置策略 + 元数据控制 。
通过以上配置,可灵活适配不同业务场景的负载均衡需求。