Spring Cloud Gateway 路由断言与过滤详解
核心概念
Spring Cloud Gateway 是基于Spring WebFlux的API网关,核心组件包括:

| 组件 | 作用 | 类比 |
|---|---|---|
| Route(路由) | 网关的基本构建块 | 快递路线 |
| Predicate(断言) | 匹配HTTP请求的条件 | 快递筛选规则 |
| Filter(过滤器) | 对请求/响应进行修改 | 快递处理工序 |
路由配置方式
YAML配置方式
spring:
cloud:
gateway:
routes:
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
filters:
- StripPrefix=1
- AddRequestHeader=X-Request-User, gateway
Java DSL配置方式
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
return builder.routes()
.route("user-service", r -> r
.path("/api/user/**")
.filters(f -> f
.stripPrefix(1)
.addRequestHeader("X-Request-User", "gateway")
)
.uri("lb://user-service")
)
.build();
}
路由断言(Predicate)详解
时间相关断言
predicates: # 在指定时间之后 - After=2024-01-01T00:00:00+08:00[Asia/Shanghai] # 在指定时间之前 - Before=2025-01-01T00:00:00+08:00[Asia/Shanghai] # 在两个时间之间 - Between=2024-06-01T00:00:00+08:00[Asia/Shanghai], 2024-12-31T23:59:59+08:00[Asia/Shanghai]
请求相关断言
predicates: # 路径匹配(支持Ant风格) - Path=/api/user/**, /api/order/** # 请求方法匹配 - Method=GET,POST # 请求头匹配 - Header=X-Request-Id, \d+ # 正则匹配 - Header=X-Request-Type, proxy # 精确匹配 # 请求参数匹配 - Query=userId, \d+ # 参数名+正则 - Query=name # 仅检查参数存在 # Cookie匹配 - Cookie=sessionId, [a-z0-9]+ # 请求体匹配 - ReadBodyPredicateFactory.class
远程地址断言
predicates: # 来源IP匹配(支持CIDR) - RemoteAddr=192.168.1.1/24, 10.0.0.0/8 # 来源主机名匹配 - Host=**.example.com, *.test.com
权重路由断言
routes:
- id: user-service-v1
uri: http://localhost:8081
predicates:
- Path=/api/user/**
- Weight=user-service, 80
- id: user-service-v2
uri: http://localhost:8082
predicates:
- Path=/api/user/**
- Weight=user-service, 20
自定义断言
@Component
public class CustomPredicateFactory
extends AbstractRoutePredicateFactory<CustomPredicateFactory.Config> {
public CustomPredicateFactory() {
super(Config.class);
}
@Override
public Predicate<ServerWebExchange> apply(Config config) {
return exchange -> {
// 自定义匹配逻辑
String header = exchange.getRequest().getHeaders()
.getFirst(config.getHeaderName());
return config.getExpectedValue().equals(header);
};
}
@Validated
public static class Config {
private String headerName;
private String expectedValue;
// getter/setter
}
}
过滤器(Filter)详解
内置过滤器分类
| 类别 | 过滤器 | 说明 |
|---|---|---|
| 请求头 | AddRequestHeader | 添加请求头 |
| RemoveRequestHeader | 移除请求头 | |
| SetRequestHeader | 设置请求头 | |
| 响应头 | AddResponseHeader | 添加响应头 |
| RemoveResponseHeader | 移除响应头 | |
| SetResponseHeader | 设置响应头 | |
| 路径 | StripPrefix | 去除路径前缀 |
| PrefixPath | 添加路径前缀 | |
| RewritePath | 重写路径 | |
| 参数 | AddRequestParameter | 添加请求参数 |
| RemoveRequestParameter | 移除请求参数 | |
| 重试 | Retry | 请求重试 |
| 限流 | RequestRateLimiter | 请求限流 |
| 熔断 | CircuitBreaker | 熔断器 |
| 其他 | RedirectTo | 重定向 |
| SetStatus | 设置HTTP状态码 | |
| DedupeResponseHeader | 响应头去重 | |
| ModifyRequestBody | 修改请求体 | |
| ModifyResponseBody | 修改响应体 |
常用过滤器示例
请求/响应头操作
filters:
- AddRequestHeader=X-Gateway,true
- AddRequestHeader=X-Request-ID, ${uuid}
- RemoveRequestHeader=Cookie
- SetResponseHeader=X-Response-Time, ${current.time}
- AddResponseHeader=X-Powered-By, Spring Gateway
路径操作
# 请求: /api/user/123
# 配置: StripPrefix=2
# 转发: /123
filters:
- StripPrefix=2
# 请求: /user/123
# 配置: PrefixPath=/api
# 转发: /api/user/123
filters:
- PrefixPath=/api
# 使用正则重写
filters:
- RewritePath=/api/user/(?<segment>.*), /$\{segment}
重试机制
filters:
- name: Retry
args:
retries: 3
statuses: BAD_GATEWAY, SERVICE_UNAVAILABLE
methods: GET, POST
series: SERVER_ERROR
限流
filters:
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
redis-rate-limiter.requestedTokens: 1
key-resolver: "#{@userKeyResolver}"
熔断
filters:
- name: CircuitBreaker
args:
name: myCircuitBreaker
fallbackUri: forward:/fallback
statusCodes:
- BAD_GATEWAY
- SERVICE_UNAVAILABLE
自定义过滤器
GlobalFilter(全局过滤器)
@Component
public class CustomGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 前置处理
ServerHttpRequest request = exchange.getRequest().mutate()
.header("X-Global-Filter", "true")
.build();
// 继续链式处理
return chain.filter(exchange.mutate().request(request).build())
.then(Mono.fromRunnable(() -> {
// 后置处理
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("X-Global-Filter", "processed");
}));
}
@Override
public int getOrder() {
return -1; // 优先级,数值越小优先级越高
}
}
GatewayFilter(路由过滤器)
@Component
public class CustomGatewayFilterFactory
extends AbstractGatewayFilterFactory<CustomGatewayFilterFactory.Config> {
public CustomGatewayFilterFactory() {
super(Config.class);
}
@Override
public String name() {
return "CustomFilter";
}
@Override
public GatewayFilter apply(Config config) {
return (exchange, chain) -> {
// 获取配置
String param = config.getParam();
// 修改请求
ServerHttpRequest request = exchange.getRequest();
// 自定义逻辑
return chain.filter(exchange);
};
}
@Validated
public static class Config {
private String param;
// getter/setter
}
}
完整配置示例
spring:
cloud:
gateway:
routes:
# 用户服务路由
- id: user-service
uri: lb://user-service
predicates:
- Path=/api/user/**
- Method=GET,POST,PUT,DELETE
- Header=X-Request-Source, web|mobile
filters:
- StripPrefix=1
- AddRequestHeader=X-Gateway-Source, gateway
- name: Retry
args:
retries: 2
statuses: BAD_GATEWAY
- name: RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 100
redis-rate-limiter.burstCapacity: 200
key-resolver: "#{@ipKeyResolver}"
# 订单服务路由(灰度发布)
- id: order-service-v1
uri: lb://order-service-v1
predicates:
- Path=/api/order/**
- Weight=order-service, 80
filters:
- StripPrefix=1
- AddResponseHeader=X-Version, v1
- id: order-service-v2
uri: lb://order-service-v2
predicates:
- Path=/api/order/**
- Weight=order-service, 20
- Header=X-Version, v2
filters:
- StripPrefix=1
- AddResponseHeader=X-Version, v2
# 回退路由
- id: fallback
uri: forward:/fallback
predicates:
- Path=/fallback
# 全局过滤器配置
default-filters:
- DedupeResponseHeader=Access-Control-Allow-Origin
# CORS配置
globalcors:
cors-configurations:
'[/**]':
allowedOrigins: "https://example.com"
allowedMethods:
- GET
- POST
allowedHeaders: "*"
性能优化建议
- 合理使用断言顺序:将命中率高的断言放在前面
- 避免过多过滤器:每个过滤器都会增加处理开销
- 使用异步处理:尽量使用非阻塞操作
- 缓存处理:对于重复计算的结果进行缓存
- 监控和日志:合理配置日志级别,避免过多日志影响性能
常见问题解决
- 404错误:检查路由断言是否匹配
- 超时问题:配置熔断和降级策略
- 请求头丢失:检查是否需要配置过滤器
- 循环路由:避免路由到自身服务
这个框架提供了强大的路由和过滤能力,能够满足大部分API网关需求,根据实际业务场景选择合适的断言和过滤器组合即可。