Spring WebFlux从WebFilter到Controller性能骤降的原因与优化咨询
spring webflux version: 2.7.2
我测试了一个简单的Spring WebFlux项目(测试时启用了SSL/TLS,但无SSL/TLS时问题仍存在),发现两种场景性能差异极大:HTTP请求进入WebFilter后立即返回、HTTP请求进入Controller后立即返回。
在4核CPU环境下,使用Apache Bench测试的TPS如下:
- HTTP请求进入WebFilter后立即返回:67000
- HTTP请求进入Controller后立即返回:20000~30000
额外测试条件:
- WebFilter中仅添加
keep-alive响应头后直接返回响应(代码如下) - WebFilter后无自定义代码,下一个组件为Controller
- Controller未使用
@Autowired注入 - Controller方法通过
@RequestBody获取小体积参数(示例中message为16字节,代码如下)
代码示例
MyFilter
public class MyFilter implements WebFilter { @Override public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) { exchange.getResponse().getHeaders().add("keep-alive", "true"); // 直接返回响应时执行此代码 return exchange.getResponse().writeWith(Mono.just(DefaultDataBufferFactory.sharedInstance.wrap("hello".getBytes()))); // 继续执行后续链时执行此代码 // return chain.filter(exchange); } }
MyController
@RestController public class MyController { @PostMapping("/hello") public Mono<HelloBody> hello(@RequestBody HelloBody helloBody) { return Mono.just(helloBody); } public static class HelloBody { private String message; // get/set方法 } }
请求处理链路长度差异
WebFilter直接返回时,跳过了Spring WebFlux核心处理的大量环节:请求路由匹配、@RequestBody对应的JSON反序列化、Controller方法反射调用、响应体序列化等。这些步骤每一步都会产生CPU开销和调度成本,累积后直接拉低TPS。序列化/反序列化开销
即使是16字节的小数据,Jackson处理JSON与Java对象的转换时,也要涉及对象创建、反射调用、JSON结构解析等CPU密集型操作,高并发下这类开销会被放大,成为性能瓶颈。核心组件调度成本
请求进入Controller链路时,会经过RequestMappingHandlerMapping路由匹配、RequestMappingHandlerAdapter方法调用,还有内置拦截器、参数解析器、返回值处理器的一系列调用。这些组件的调度逻辑虽经过优化,但高并发下依然会产生可观损耗,而WebFilter直接返回时完全跳过了这些流程。
跳过不必要的序列化环节
如果业务不需要解析请求体或返回复杂对象,直接在WebFilter层处理请求;若必须用Controller,可直接通过ServerHttpRequest获取原始字节流,避免自动JSON序列化/反序列化。优化序列化组件
- 替换Jackson为更轻量的JSON库(如Fastjson2、Gson),小对象场景下性能更优;
- 针对高频DTO类,自定义序列化/反序列化实现(比如用Lombok注解生成模板代码、Jackson的
@JsonCreator减少反射调用)。
- 缩短请求处理链路
- 无复杂业务逻辑的请求直接在WebFilter或网关层处理,不进入Controller;
- 禁用不必要的内置拦截器、参数解析器,减少链路中的处理节点。
- JVM与Netty参数调优
- 增大堆内存与直接内存,降低GC频率;使用G1/ZGC垃圾收集器,减少GC停顿;
- 调整Netty EventLoop线程数(建议设为CPU核心数的2倍),优化高并发下的线程调度效率。
内容的提问来源于stack exchange,提问作者TJwoods

