Spring Webflux响应式Mongo与Spring MVC Mongo性能差异排查
问题:Spring Webflux+响应式Mongo性能远低于Spring MVC+同步Mongo的原因分析
测试场景与性能结果
- 开发两个对比应用:一个基于Spring Webflux搭配响应式Mongo驱动,另一个基于Spring MVC搭配非响应式Mongo驱动
- 测试数据:Mongo实例中存入45000条数据
- 性能表现:
- MVC应用平均响应时间约200-300ms
- 响应式应用平均响应时间约2秒,是MVC的3倍以上
- 跨机器JMeter压测时,响应式应用性能仅为MVC的1/3
- 使用内存仓库时,两者性能相近
环境配置
Docker部署的Mongo实例配置
mongo: image: mongo restart: always env_file: - ./env/mongo.env #仅配置用户名和密码 ports: - 27017:27017 volumes: - mongodb:/data/db - mongoconfigdb:/data/configdb
应用配置(MVC与响应式一致)
application.yml:
spring: data: mongodb: uri: mongodb://admin:nimda@localhost:27017 database: data-name auto-index-creation: true application: name: data
Mongo实体类(两者一致)
@Document(collection = "data") public class Data { @Id private String id; public String getId() { return id; } public void setId(String id) { this.id = id; } }
MVC应用实现细节
Controller
@RestController public class BlockingController { private final BlockingMongoRepository blockingMongoRepository; public BlockingController(@Qualifier("blockingMongoRepository") BlockingMongoRepository blockingMongoRepository) { this.blockingMongoRepository = blockingMongoRepository; } @RequestMapping(value = "/get", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public List<Data> getAllData() { return blockingMongoRepository.findAll(); } }
Repository
@Repository(value = "blockingMongoRepository") public interface BlockingMongoRepository extends MongoRepository<Data, String> { }
依赖配置(build.gradle)
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-mongodb' implementation 'org.springframework.boot:spring-boot-starter-web' }
响应式应用实现细节
Controller
@RestController public class ReactiveController { private final DataReactiveMongoRepository dataReactiveMongoRepository; public ReactiveController(@Qualifier("dataReactiveMongoRepository") DataReactiveMongoRepository dataReactiveMongoRepository) { this.dataReactiveMongoRepository = dataReactiveMongoRepository; } @RequestMapping(value = "/get", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE) public Flux<Data> getAllData() { return dataReactiveMongoRepository.findAll(); } }
Repository
@Repository(value = "dataReactiveMongoRepository") public interface DataReactiveMongoRepository extends ReactiveMongoRepository<Data, String> { }
依赖配置(build.gradle)
dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-mongodb-reactive' implementation 'org.springframework.boot:spring-boot-starter-webflux' }
排查过程与关键发现
- 针对响应式Controller尝试修改返回格式:返回x-ndjson、将Flux转为List,性能无提升;返回单条x-ndjson格式时性能更差
- 手动添加
@EnableReactiveMongoRepositories无效果 - 连接Mongo Atlas免费实例时也出现相同性能差异(测试可靠性较低)
- 关键更新发现:
- 直接使用
org.mongodb:mongodb-driver-reactivestreams的MongoClient时,性能比MVC应用高约2.3倍 - 使用ReactiveMongoTemplate/Repository时,Blockhound检测到阻塞调用;直接用MongoClient时无此情况,推测性能损耗来自Spring Mongo Starter阻塞事件循环,但疑惑为何会影响单请求响应时间
- 直接使用
疑问
这种情况的原因是什么?是否需要额外配置才能发挥Webflux的性能优势?
内容的提问来源于stack exchange,提问作者dsajkjke
相关产品推荐
相关产品推荐

