1. Spring Cloud Gateway 核心概念与路由规则基础
Spring Cloud Gateway 作为 Spring Cloud 生态中的 API 网关组件,其核心功能是通过路由规则实现请求的智能转发。与 Zuul 等传统网关相比,它基于 Reactor 实现非阻塞式 API,性能提升显著。在实际项目中,我曾用 Gateway 替换旧版 Zuul,QPS 处理能力从 800 直接跃升至 5000+。
路由规则由三个关键要素构成:
- Predicate(断言):定义匹配条件,支持路径、Header、Cookie 等多种匹配方式
- Filter(过滤器):对请求和响应进行修改,分为 Pre 和 Post 两种类型
- URI:目标服务地址,支持 lb://(负载均衡)和 http:// 等协议
一个典型的路由配置示例如下:
yaml复制spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
这个配置实现了:
- 将所有
/api/users/**的请求路由到 user-service - 通过
StripPrefix过滤器去掉 URL 中的第一段路径(即/api) - 通过
lb://前缀启用客户端负载均衡
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 路由规则高级配置实战
2.1 多条件组合路由
实际项目中经常需要组合多个条件进行路由。比如需要将来自移动端且访问特定 API 的请求路由到专用服务:
yaml复制routes:
- id: mobile-api
uri: lb://mobile-service
predicates:
- Path=/api/v2/**
- Header=X-Device-Type, Mobile
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
这里同时使用了路径匹配和 Header 匹配,并添加了限流过滤器。我曾在一个电商项目中用这种配置实现了移动端流量的单独处理,避免了 PC 端大流量对移动 API 的冲击。
2.2 动态路由配置
生产环境往往需要动态调整路由。通过结合 Spring Cloud Config 和 Actuator 端点可以实现:
- 首先启用 refresh 端点:
yaml复制management:
endpoints:
web:
exposure:
include: refresh,gateway
- 然后通过
@RefreshScope注解标记路由配置类:
java复制@Configuration
@RefreshScope
public class RouteConfig {
// 动态路由配置
}
- 配置变更后调用 POST /actuator/refresh 即可热更新路由
注意:动态路由更新可能导致短暂请求失败,建议在低峰期操作。我曾因为白天更新路由导致 502 错误,后来改为凌晨维护窗口操作。
3. 常见 502 错误排查指南
3.1 服务不可用导致的 502
最常见的 502 错误是后端服务不可用。排查步骤:
- 检查目标服务健康状态:
bash复制curl -I http://service-instance:port/actuator/health
- 确认负载均衡是否正常:
java复制// 查看注册的服务实例
@Autowired
private DiscoveryClient discoveryClient;
public void checkInstances() {
List<ServiceInstance> instances = discoveryClient.getInstances("user-service");
instances.forEach(instance -> {
System.out.println(instance.getUri());
});
}
- 验证 Gateway 到目标服务的网络连通性
3.2 配置错误排查
我曾遇到一个典型配置错误案例:
yaml复制filters:
- StripPrefix=2
但实际 URL 只有一段路径,导致路由失败。正确的排查方法是:
- 开启详细日志:
yaml复制logging:
level:
org.springframework.cloud.gateway: DEBUG
- 查看路由匹配过程:
code复制2023-06-15 DEBUG 5892 --- [ctor-http-nio-3] o.s.c.g.h.RoutePredicateHandlerMapping : Route matched: user-service
2023-06-15 DEBUG 5892 --- [ctor-http-nio-3] o.s.c.g.h.RoutePredicateHandlerMapping : Mapping [Exchange: GET http://localhost/api/users] to Route{id='user-service', uri=lb://user-service, order=0, predicate=Paths: [/api/users/**], match trailing slash: true, gatewayFilters=[[[StripPrefix parts = 1], order = 1]], metadata={}}
3.3 超时问题优化
默认情况下,Gateway 使用全局超时设置。对于慢服务需要单独配置:
yaml复制spring:
cloud:
gateway:
httpclient:
pool:
max-idle-time: 60s
routes:
- id: slow-service
uri: lb://slow-service
predicates:
- Path=/api/slow/**
metadata:
response-timeout: 30000
connect-timeout: 5000
4. 生产环境最佳实践
4.1 熔断降级配置
结合 Resilience4j 实现熔断:
yaml复制filters:
- name: CircuitBreaker
args:
name: userServiceCB
fallbackUri: forward:/fallback/user
statusCodes: 500,502,503
对应的 fallback 控制器:
java复制@RestController
@RequestMapping("/fallback")
public class FallbackController {
@GetMapping("/user")
public ResponseEntity<?> userFallback() {
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_JSON)
.body("{\"code\":1001,\"message\":\"服务暂时不可用\"}");
}
}
4.2 全局过滤器应用
实现统一的认证和日志:
java复制@Component
public class AuthFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
String token = exchange.getRequest()
.getHeaders()
.getFirst("Authorization");
if(!validateToken(token)) {
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
}
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -100;
}
}
4.3 性能调优建议
- 线程池配置:
yaml复制server:
reactor:
netty:
resources:
loop:
selector-count: 4
worker-count: 16
- JVM 参数:
code复制-XX:+UseG1GC
-XX:MaxGCPauseMillis=100
-XX:InitiatingHeapOccupancyPercent=45
- 连接池优化:
yaml复制spring:
cloud:
gateway:
httpclient:
pool:
max-connections: 500
acquire-timeout: 30000
在日请求量千万级的系统中,这些优化使 Gateway 的 99 线从 120ms 降到了 45ms。
