Spring Boot 3.3.4迁移后Actuator健康检查报Mongo 'hello'命令错误
问题:Spring Boot 3.3.4迁移后Mongo健康检查单元测试失败
问题背景
将应用从Spring Boot 3.3.3版本迁移至3.3.4版本后,所有单元测试均正常运行,唯有/actuator/health的健康检查单元测试失败,该测试在3.3.3版本下无异常。已知MongoDB从5.0版本开始引入hello健康检查命令,当前使用的嵌入式Mongo不支持该命令,导致健康检查失败。
项目依赖配置
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>3.3.4</version> </parent> <dependencies> <dependency> <groupId>de.bwaldvogel</groupId> <artifactId>mongo-java-server</artifactId> <version>1.44.0</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- METRICs --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>io.micrometer</groupId> <artifactId>micrometer-registry-prometheus</artifactId> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${version.spring-webmvc}</version> </dependency> </dependencies>
单元测试代码
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; import java.util.Map; import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.ActiveProfiles; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.TestPropertySource; import org.springframework.test.web.servlet.MockMvc; import org.springframework.test.web.servlet.setup.MockMvcBuilders; import org.springframework.web.context.WebApplicationContext; import com.xxx.xxx.api.absenceservice.config.ConnectionConfig; import com.fasterxml.jackson.databind.ObjectMapper; @SpringBootTest @EnableAutoConfiguration @ActiveProfiles({"test"}) @ContextConfiguration(classes = {ConnectionConfig.class}) @TestPropertySource(locations="classpath:test.properties") public class MetricsTest { @Autowired private WebApplicationContext context; private MockMvc mockMvc; @BeforeEach public void init() { this.mockMvc = MockMvcBuilders.webAppContextSetup(this.context).build(); } @Test public void shouldCheckHealthcheck() throws Exception { final String url = "/actuator/health"; this.mockMvc.perform(get(url).header("Content-Type", "application/json")) .andExpect(status().isOk()) .andDo(response -> { final Map<String, String> metricsResponse = new ObjectMapper().readValue(response.getResponse().getContentAsString(), Map.class); Assertions.assertEquals("UP", metricsResponse.get("status")); }); } }
错误日志
2024-10-17T09:07:38.808+02:00 ERROR 26448 --- [-server-worker3] d.b.mongo.backend.AbstractMongoDatabase : unknown query: {"hello" : 1, "$db" : "test"} 2024-10-17T09:07:38.819+02:00 ERROR 26448 --- [-server-worker3] d.b.mongo.wire.MongoWireProtocolHandler : failed to handle {"hello" : 1, "$db" : "test"} de.bwaldvogel.mongo.exception.NoSuchCommandException: [Error 59] no such command: 'hello' at de.bwaldvogel.mongo.backend.AbstractMongoDatabase.handleCommand(AbstractMongoDatabase.java:181) ~[mongo-java-server-core-1.44.0.jar:na] at de.bwaldvogel.mongo.backend.AbstractMongoBackend.handleCommand(AbstractMongoBackend.java:339) ~[mongo-java-server-core-1.44.0.jar:na] at de.bwaldvogel.mongo.backend.AbstractMongoBackend.handleMessage(AbstractMongoBackend.java:412) ~[mongo-java-server-core-1.44.0.jar:na] at de.bwaldvogel.mongo.wire.MongoDatabaseHandler.handleMessage(MongoDatabaseHandler.java:73) ~[mongo-java-server-core-1.44.0.jar:na] at de.bwaldvogel.mongo.wire.MongoDatabaseHandler.channelRead0(MongoDatabaseHandler.java:62) ~[mongo-java-server-core-1.44.0.jar:na] at de.bwaldvogel.mongo.wire.MongoDatabaseHandler.channelRead0(MongoDatabaseHandler.java:27) ~[mongo-java-server-core-1.44.0.jar:na] at io.netty.channel.SimpleChannelInboundHandler.channelRead(SimpleChannelInboundHandler.java:99) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.handler.codec.ByteToMessageDecoder.fireChannelRead(ByteToMessageDecoder.java:346) ~[netty-codec-4.1.113.Final.jar:4.1.113.Final] at io.netty.handler.codec.ByteToMessageDecoder.channelRead(ByteToMessageDecoder.java:318) ~[netty-codec-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:444) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.AbstractChannelHandlerContext.fireChannelRead(AbstractChannelHandlerContext.java:412) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.DefaultChannelPipeline$HeadContext.channelRead(DefaultChannelPipeline.java:1357) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:440) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.AbstractChannelHandlerContext.invokeChannelRead(AbstractChannelHandlerContext.java:420) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.DefaultChannelPipeline.fireChannelRead(DefaultChannelPipeline.java:868) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.nio.AbstractNioByteChannel$NioByteUnsafe.read(AbstractNioByteChannel.java:166) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKey(NioEventLoop.java:788) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeysOptimized(NioEventLoop.java:724) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.nio.NioEventLoop.processSelectedKeys(NioEventLoop.java:650) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:562) ~[netty-transport-4.1.113.Final.jar:4.1.113.Final] at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997) ~[netty-common-4.1.113.Final.jar:4.1.113.Final] at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74) ~[netty-common-4.1.113.Final.jar:4.1.113.Final] at java.base/java.lang.Thread.run(Thread.java:833) ~[na:na] 2024-10-17T09:07:38.837+02:00 WARN 26448 --- [ main] o.s.b.a.data.mongo.MongoHealthIndicator : MongoDB health check failed
解决思路
- 升级嵌入式Mongo版本:当前使用的
mongo-java-server 1.44.0不支持MongoDB 5.0+引入的hello命令,升级到1.49.0及以上版本(该版本开始支持hello命令)。修改Maven依赖:<dependency> <groupId>de.bwaldvogel</groupId> <artifactId>mongo-java-server</artifactId> <version>1.49.0</version> <scope>test</scope> </dependency> - 配置使用旧版健康检查命令:如果暂时无法升级嵌入式Mongo,可在测试环境配置文件
test.properties中添加以下配置,强制Spring Boot使用旧版的isMaster命令进行健康检查:spring.data.mongodb.health-check.command=isMaster - 临时禁用Mongo健康检查:若测试不需要验证Mongo健康状态,可临时关闭Mongo健康指示器,添加配置:
此方案仅作临时应急,长期使用会丢失健康检查的验证能力,不推荐。management.health.mongo.enabled=false
内容的提问来源于stack exchange,提问作者Wilfried
相关产品推荐
相关产品推荐

