SpringBoot中MongoDB连接超时配置不生效问题排查
SpringBoot中MongoDB连接超时设置未生效的问题
问题描述
在SpringBoot应用中配置MongoDB连接超时参数后未按预期生效:
- 期望Mongo连接请求在2秒后超时,健康检查返回"DOWN"
- 实际等待30秒才抛出异常并返回状态
配置信息
application.yml
spring: data: mongodb: uri: mongodb://localhost:27017/messaging
MongoConfig.java
@Slf4j @Configuration public class MongoConfig { @Bean public MongoClientSettingsBuilderCustomizer mongoConnectionSettings() { return builder -> { builder.applyToSocketSettings( bldr -> bldr.connectTimeout(2000, TimeUnit.MILLISECONDS) .readTimeout(5500, TimeUnit.MILLISECONDS)); }; } }
验证步骤
- 启动MongoDB服务与应用,访问Actuator健康检查接口
http://localhost:8080/actuator/health/mongo,状态显示"UP" - 停止MongoDB服务,再次访问该接口,实际等待30秒才返回"DOWN"
异常日志
org.mongodb.driver.cluster : Cluster description not yet available. Waiting for 30000 ms before timing out o.s.b.a.data.mongo.MongoHealthIndicator : MongoDB health check failed org.springframework.dao.DataAccessResourceFailureException: Timed out after 30000 ms while waiting to connect. Client view of cluster state is {type=UNKNOWN, servers=[{address=localhost:27017, type=UNKNOWN, state=CONNECTING, exception={com.mongodb.MongoSocketOpenException: Exception opening socket}, caused by {java.net.ConnectException: Connection refused}}] at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java:93) at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java:2932) at org.springframework.data.mongodb.core.MongoTemplate.execute(MongoTemplate.java:581) at org.springframework.data.mongodb.core.MongoTemplate.executeCommand(MongoTemplate.java:513) at org.springframework.boot.actuate.data.mongo.MongoHealthIndicator.doHealthCheck(MongoHealthIndicator.java:46) at org.springframework.boot.actuate.health.AbstractHealthIndicator.health(AbstractHealthIndicator.java:82) at org.springframework.boot.actuate.health.HealthIndicator.getHealth(HealthIndicator.java:37)
问题原因
你配置的connectTimeout是单个Socket连接到MongoDB节点的超时时间,而日志中显示的30秒是MongoDB客户端的服务器选择超时(serverSelectionTimeout)——这是客户端等待集群返回可用服务器描述的默认超时时间。
当MongoDB服务停止后,健康检查请求触发客户端尝试连接集群,客户端会在超时时间内持续尝试获取可用服务器,直到serverSelectionTimeout到期才会抛出超时异常,而非你设置的Socket连接超时。
解决方案
需要同时配置服务器选择超时,才能让健康检查在预期的2秒内返回状态。
方案1:修改MongoConfig配置类
在MongoClientSettingsBuilderCustomizer中添加serverSelectionTimeout配置:
@Slf4j @Configuration public class MongoConfig { @Bean public MongoClientSettingsBuilderCustomizer mongoConnectionSettings() { return builder -> { // 配置Socket连接和读取超时 builder.applyToSocketSettings(bldr -> bldr.connectTimeout(2000, TimeUnit.MILLISECONDS) .readTimeout(5500, TimeUnit.MILLISECONDS)); // 配置服务器选择超时 builder.serverSelectionTimeout(2000, TimeUnit.MILLISECONDS); }; } }
方案2:通过MongoDB URI直接配置参数
在application.yml的MongoDB URI中添加对应参数,更简洁直观:
spring: data: mongodb: uri: mongodb://localhost:27017/messaging?connectTimeoutMS=2000&serverSelectionTimeoutMS=2000&socketTimeoutMS=5500
参数说明
connectTimeoutMS:单个Socket连接到MongoDB节点的超时时间serverSelectionTimeoutMS:客户端等待集群返回可用服务器的超时时间,对应你遇到的30秒默认值socketTimeoutMS:Socket读取操作的超时时间,对应代码中的readTimeout
内容的提问来源于stack exchange,提问作者RKodakandla
相关产品推荐
相关产品推荐

