Spring WebFlux架构与阻塞模型对比
分析Spring WebFlux的架构设计,包括其底层的Reactor Netty实现、对比传统Spring MVC的Servlet阻塞模型、以及WebFlux在性能方面的优势和适用场景。
回答
我还是少年
1. WebFlux架构
- 底层:Reactor Netty(基于Netty的异步驱动)
- 支持的Server:Netty / Undertow / Jetty / Tomcat(Servlet 3.1异步)
- 不依赖Servlet API,基于Reactive Streams规范
2. WebFlux vs Spring MVC | 特性 | Spring MVC | Spring WebFlux | |------|------|------| | 编程模型 | 同步阻塞 | 异步非阻塞 | | 底层API | Servlet API | Reactive Streams | | 线程模型 | 请求线程池(Tomcat ~200线程) | EventLoop(~CPU核数×2) | | 数据访问 | JPA/JDBC(阻塞) | R2DBC/MongoDB Reactive | | 返回类型 | ResponseEntity/ModelAndView | Mono/Flux/WebFluxResponse | | 适用场景 | 传统企业应用、计算密集型 | I/O密集型、高并发网关 |
3. 编程示例
@RestController
public class UserController {
@GetMapping("/users/{id}")
public Mono<User> getUser(@PathVariable String id) {
return userRepository.findById(id)
.switchIfEmpty(Mono.error(new UserNotFoundException()));
}
@GetMapping("/users")
public Flux<User> listUsers() {
return userRepository.findAll();
}
// 函数式路由(RouterFunction)
@Bean
public RouterFunction<ServerResponse> routes() {
return route(GET("/api/users/{id}"),
req -> ok().body(userRepo.findById(req.pathVariable("id")), User.class));
}
}
4. 性能优势
- 少量线程处理大量并发连接
- 避免线程上下文切换开销
- 背压机制保护下游系统
- 最适合I/O密集型:
- 网关(Spring Cloud Gateway基于WebFlux)
- REST API(频繁数据库/服务调用)
- 实时数据推送(SSE/WebSocket)
5. 限制
- 计算密集型任务阻塞EventLoop线程
- JDBC是阻塞的,需用R2DBC
- 调试复杂度高(响应式调用栈深)
- ThreadLocal不适用(线程切换)