前言:为什么需要网关负载均衡?
在微服务架构中,API网关作为流量的入口,其高可用性至关重要。如果只有一个网关实例,一旦出现故障,整个系统将面临服务中断的风险。通过部署多个网关实例并结合负载均衡策略,我们可以实现:
- 高可用性:单个实例故障不影响整体服务
- 弹性伸缩:根据流量动态调整网关实例数量
- 灵活路由:根据不同场景采用合适的负载均衡策略
本文将基于Spring Cloud Gateway 2022.0.0+、Spring Boot 3.x和Nacos 2.x,演示如何实现多网关实例的负载均衡。
一、环境准备与项目搭建
1.1 技术栈版本
<properties>
<java.version>17</java.version>
<spring-boot.version>3.0.2</spring-boot.version>
<spring-cloud.version>2022.0.0</spring-cloud.version>
<spring-cloud-alibaba.version>2022.0.0.0</spring-cloud-alibaba.version>
</properties>
1.2 项目结构
gateway-loadbalance-demo/
├── gateway-service-8001
├── gateway-service-8002
├── user-service-8081
├── user-service-8082
└── nacos-server
1.3 核心依赖配置
网关服务pom.xml:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-loadbalancer</artifactId>
</dependency>
</dependencies>
二、双网关实例部署实战
2.1 网关配置类
@Configuration
public class GatewayConfig {
@Bean
@LoadBalanced
public WebClient.Builder loadBalancedWebClientBuilder() {
return WebClient.builder();
}
}
2.2 第一个网关实例 (端口8001)
application.yml:
server:
port: 8001
spring:
application:
name: gateway-service
cloud:
nacos:
discovery:
server-addr: localhost:8848
namespace: public
group: DEFAULT_GROUP
gateway:
discovery:
locator:
enabled: true
lower-case-service-id: true
routes:
- id: user-service-route
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
key-resolver: "#{@userKeyResolver}"
logging:
level:
org.springframework.cloud.gateway: DEBUG
reactor.netty.http.client: DEBUG
2.3 第二个网关实例 (端口8002)
复制8001的配置,仅修改端口:
server:
port: 8002
# 其他配置与8001相同
2.4 用户服务提供者
创建两个用户服务实例(8081和8082端口),用于测试负载均衡效果。
UserController.java:
@RestController
@RequestMapping("/users")
@Slf4j
public class UserController {
@Value("${server.port}")
private String port;
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
log.info("用户服务[{}]处理请求,用户ID: {}", port, id);
User user = User.builder()
.id(id)
.name("用户-" + id)
.email("user" + id + "@example.com")
.servicePort(port)
.timestamp(System.currentTimeMillis())
.build();
return ResponseEntity.ok(user);
}
@GetMapping("/health")
public ResponseEntity<Map<String, String>> health() {
Map<String, String> health = new HashMap<>();
health.put("status", "UP");
health.put("port", port);
health.put("timestamp", String.valueOf(System.currentTimeMillis()));
return ResponseEntity.ok(health);
}
}
三、Nacos服务注册与发现
3.1 服务注册状态验证
启动所有服务后,登录Nacos控制台(http://localhost:8848/nacos),应该看到如下服务列表:
- gateway-service (2个实例:8001, 8002)
- user-service (2个实例:8081, 8082)


2066

被折叠的 条评论
为什么被折叠?



