1. Spring Cloud Gateway 路由规则基础概念
Spring Cloud Gateway作为Spring Cloud生态中的API网关组件,其核心功能之一就是路由规则的配置与管理。路由规则决定了请求如何从客户端流转到后端服务,是整个网关系统的"交通指挥中心"。
路由(Route)由三个基本要素构成:
- ID:路由的唯一标识符,用于区分不同路由
- URI:路由指向的目标地址,支持HTTP、WebSocket等协议
- Predicate:匹配请求的条件集合,决定哪些请求会被该路由处理
- Filter:对请求和响应进行修改的处理器链
一个典型的路由配置示例如下:
yaml复制spring:
cloud:
gateway:
routes:
- id: user-service
uri: http://localhost:8081
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1
2. 路由规则配置详解
2.1 基于配置文件的路由配置
YAML格式的配置文件是最常见的路由配置方式,支持两种配置风格:
简洁风格:
yaml复制spring:
cloud:
gateway:
routes:
- id: order-service
uri: http://localhost:8082
predicates:
- Path=/api/orders/**
完整风格:
yaml复制spring:
cloud:
gateway:
routes:
- id: order-service
uri: http://localhost:8082
predicates:
- name: Path
args:
pattern: /api/orders/**
提示:完整风格虽然冗长,但在需要配置多个相同类型谓词时更为清晰,如配置多个Header匹配条件。
2.2 基于Java代码的动态路由
对于需要动态变更路由的场景,可以通过编程方式注册路由:
java复制@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("payment-service", r -> r.path("/api/payments/**")
.filters(f -> f.stripPrefix(1))
.uri("http://localhost:8083"))
.build();
}
动态路由的优势在于:
- 可以根据运行时条件动态调整路由规则
- 与配置中心(如Nacos、Consul)集成实现热更新
- 支持从数据库等外部源加载路由配置
3. 路由谓词(Predicate)详解
谓词决定了请求是否匹配特定路由,Spring Cloud Gateway内置了丰富的谓词工厂:
3.1 常用谓词类型
| 谓词类型 | 示例配置 | 匹配条件说明 |
|---|---|---|
| Path | - Path=/api/** | 请求路径匹配指定模式 |
| Method | - Method=GET,POST | 请求方法匹配指定HTTP方法 |
| Header | - Header=X-Request-Id, \d+ | 请求头包含指定名称且值匹配正则 |
| Query | - Query=name, zhangsan | 查询参数包含指定名称且值匹配 |
| Cookie | - Cookie=sessionId, .+ | Cookie包含指定名称且值匹配正则 |
| After | - After=2023-01-20T17:42:47.789Z | 请求时间在指定日期时间之后 |
| Before | - Before=2023-12-31T23:59:59Z | 请求时间在指定日期时间之前 |
| Between | - Between=上午9:00, 下午5:00 | 请求时间在指定时间范围内 |
| RemoteAddr | - RemoteAddr=192.168.1.1/24 | 请求IP在指定CIDR范围内 |
3.2 谓词组合逻辑
多个谓词默认采用AND逻辑,即所有条件必须同时满足:
yaml复制predicates:
- Path=/api/orders/**
- Method=POST
- Header=X-Auth-Token, .+
可以通过自定义RoutePredicateFactory实现更复杂的逻辑组合。
4. 过滤器(Filter)配置与使用
过滤器用于在请求被路由前后修改请求和响应内容,分为"pre"和"post"两种类型。
4.1 内置过滤器示例
请求路径处理:
yaml复制filters:
- StripPrefix=2 # 去除前两级路径
请求头修改:
yaml复制filters:
- AddRequestHeader=X-Request-Id, 12345
- RemoveRequestHeader=Cookie
响应修改:
yaml复制filters:
- AddResponseHeader=X-Response-Time, $(took)
- SetStatus=401
重试机制:
yaml复制filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY, SERVICE_UNAVAILABLE
methods: GET,POST
4.2 自定义过滤器实现
对于特殊需求,可以创建自定义过滤器:
java复制@Component
public class CustomFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 前置处理逻辑
long startTime = System.currentTimeMillis();
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
// 后置处理逻辑
long duration = System.currentTimeMillis() - startTime;
exchange.getResponse().getHeaders().add("X-Response-Time", duration + "ms");
}));
}
@Override
public int getOrder() {
return -1; // 过滤器执行顺序
}
}
5. 高级路由场景与最佳实践
5.1 负载均衡路由配置
集成服务发现组件后,可以实现基于服务名的负载均衡路由:
yaml复制spring:
cloud:
gateway:
routes:
- id: user-service-lb
uri: lb://user-service # lb://表示负载均衡
predicates:
- Path=/api/users/**
5.2 熔断降级配置
集成Resilience4j实现熔断:
yaml复制filters:
- name: CircuitBreaker
args:
name: userServiceCB
fallbackUri: forward:/fallback/user
statusCodes: 500,503
对应的降级处理端点:
java复制@RestController
public class FallbackController {
@GetMapping("/fallback/user")
public ResponseEntity<String> userFallback() {
return ResponseEntity.status(HttpStatus.SERVICE_UNAVAILABLE)
.body("User service is temporarily unavailable");
}
}
5.3 跨域配置
全局CORS配置示例:
yaml复制spring:
cloud:
gateway:
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "*"
allowedMethods:
- GET
- POST
- PUT
- DELETE
allowedHeaders: "*"
maxAge: 3600
5.4 502/504错误排查
针对热词中频繁出现的502 Bad Gateway和504 Gateway Timeout错误,常见排查步骤:
-
检查后端服务可用性:
bash复制
curl -v http://backend-service:port/health -
调整连接超时设置:
yaml复制spring: cloud: gateway: httpclient: connect-timeout: 1000 response-timeout: 5s -
检查路由配置正确性:
- 确认URI格式正确(http://或lb://前缀)
- 验证谓词匹配规则是否过于宽松或严格
-
启用详细日志:
yaml复制logging: level: org.springframework.cloud.gateway: DEBUG reactor.netty: DEBUG
6. 性能优化与生产建议
6.1 路由缓存优化
对于静态路由配置,启用路由缓存提升性能:
java复制@Bean
public RouteDefinitionLocator cachedRouteDefinitionLocator(RouteDefinitionLocator delegate) {
return new CachingRouteDefinitionLocator(delegate);
}
6.2 线程池调优
根据负载情况调整事件循环线程数:
yaml复制spring:
cloud:
gateway:
httpclient:
pool:
max-connections: 500
acquire-timeout: 5000
6.3 监控与指标
集成Micrometer暴露网关指标:
yaml复制management:
endpoints:
web:
exposure:
include: health,info,metrics,gateway
metrics:
tags:
application: ${spring.application.name}
关键监控指标包括:
gateway.requests:请求计数http.server.requests:响应时间分布reactor.netty.connection.provider:连接池状态
6.4 安全加固建议
-
禁用管理端点:
yaml复制management: endpoints: web: exposure: exclude: gateway -
请求头过滤:
yaml复制spring: cloud: gateway: default-filters: - RemoveRequestHeader=Authorization -
速率限制:
yaml复制filters: - name: RequestRateLimiter args: redis-rate-limiter.replenishRate: 100 redis-rate-limiter.burstCapacity: 200
在实际生产部署中,我们通常会结合Kubernetes Ingress或Service Mesh来管理Gateway实例,实现更高层次的流量控制和观测能力。对于微服务架构,建议将Gateway与服务注册中心深度集成,实现服务的自动发现和动态路由。
