OpenShift环境中Spring Boot并行查询R2DBC MSSQL引发异常
问题原因分析
这个问题的核心是R2DBC连接池资源在并行查询时被耗尽,具体细节如下:
- Reactor
flatMap的并行特性:直接使用findAllThings().flatMap(lookupForOneThing)时,flatMap默认会以并行方式处理上游的每个元素(默认并发数等于CPU核心数),这会同时发起多个数据库查询请求,快速消耗R2DBC连接池中的可用连接。 - OpenShift环境的连接池限制:在OpenShift容器化环境中,通常会对数据库连接池的大小做更严格的资源限制,当并行请求数超过连接池的最大可用连接数时,就会出现获取数据库连接失败的情况,抛出
DataAccessResourceFailureException。 - 本地与OpenShift环境的差异:本地开发环境的连接池配置通常更宽松,或者并发请求量小,并行查询不会触发连接耗尽的问题,因此本地运行正常。
而改成串行执行的代码(collectList().flatMapIterable(it).flatMap(...)),会先把上游所有元素收集到列表中,再逐个串行处理,同一时间只会发起一个数据库查询,不会超过连接池的承载能力,因此异常消失。
解决方案建议
- 限制
flatMap的并发数:无需完全改成串行,通过flatMap的重载方法指定合理的并发数,匹配连接池的承载能力:findAllThings() .flatMap(lookupForOneThing, 3) // 根据连接池大小调整并发数 ... - 调整R2DBC连接池配置:在配置文件中增大连接池的最大连接数(注意要和Azure SQL的连接配额匹配,避免超出数据库的连接限制):
spring: r2dbc: pool: max-size: 8 # 根据实际资源情况调整 - 优化查询逻辑:如果允许,尽量在数据库层面完成JOIN操作,减少应用层的多次查询,从根源上降低连接资源的消耗。
内容的提问来源于stack exchange,提问作者kschlesselmann
相关产品推荐
相关产品推荐

