理解过滤器类型与生命周期
Spring Cloud Gateway的过滤器分为全局过滤器(GlobalFilter)和路由过滤器(GatewayFilter)。全局过滤器对所有路由生效,路由过滤器仅对特定路由生效。过滤器生命周期包含pre(路由前处理)和post(响应后处理)两个阶段,需明确业务逻辑的执行时机。
正确实现Ordered接口
自定义过滤器需实现Ordered接口或使用@Order注解指定执行顺序。顺序值越小优先级越高,全局过滤器默认按Ordered.LOWEST_PRECEDENCE执行。若未正确设置顺序,可能导致过滤器链逻辑混乱。
public class CustomFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
// 业务逻辑
return chain.filter(exchange);
}
@Override
public int getOrder() {
return -1; // 高优先级
}
}
异常处理与响应修改
在过滤器中修改响应时,需通过ServerWebExchange的mutate()方法创建新响应。直接操作原始响应可能导致数据不一致。捕获异常时建议使用Mono.error或自定义错误页面:
exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
return exchange.getResponse().setComplete();
避免阻塞操作
Gateway基于Reactor非阻塞模型,禁止在过滤器中调用阻塞式API(如JDBC同步查询)。若需访问数据库,应使用响应式驱动(如R2DBC)或通过Mono.fromCallable封装阻塞调用并指定调度器:
return Mono.fromCallable(() -> blockingService.query())
.subscribeOn(Schedulers.boundedElastic())
.flatMap(result -> chain.filter(exchange));
合理缓存请求体
网关可能需要多次读取请求体(如验签、日志)。默认情况下请求体只能读取一次,需通过CacheRequestBodyFilter缓存或使用以下代码:
ServerHttpRequestDecorator decorator = new ServerHttpRequestDecorator(request) {
@Override
public Flux<DataBuffer> getBody() {
return cachedBodyFlux; // 缓存后的数据
}
};
return chain.filter(exchange.mutate().request(decorator).build());
性能监控与日志
通过Micrometer集成监控过滤器耗时,避免在高频路径中打印完整请求日志。建议对敏感信息脱敏,并动态开关日志级别:
Metrics.timer("filter.custom.timer").record(() -> {
// 业务逻辑
});
测试策略
使用WebTestClient模拟网关请求,验证过滤器行为。特别注意测试以下场景:
- 带Body的POST请求过滤
- 异常路径处理
- 响应头修改
- 并发请求下的线程安全
@SpringBootTest
class FilterTest {
@Autowired
private WebTestClient webClient;
@Test
void testFilter() {
webClient.post().uri("/route")
.header("Authorization", "token")
.exchange()
.expectStatus().isOk();
}
}
2212

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



