High number of connections due to Mongo health indicator#50734
High number of connections due to Mongo health indicator#50734seonwooj0810 wants to merge 2 commits into
Conversation
The MongoDB health indicators ran the `hello` command against every database returned by `listDatabaseNames()`. For the reactive indicator these commands were issued in parallel via `flatMap`, so a deployment with many databases per connection could open a connection per database on each health check, dramatically increasing connection usage (a regression from the Spring Data based implementation used previously). Since `hello` is a server-level command whose result is independent of the target database, run it only once against the `admin` database. The `databases` and `maxWireVersion` details are preserved. See spring-projectsgh-50727 Signed-off-by: seonwoo_jung <79202163+seonwooj0810@users.noreply.github.com>
wilkinsona
left a comment
There was a problem hiding this comment.
Thanks for the PR, @seonwooj0810. I've left a comment for your consideration.
| }); | ||
| builder.up().withDetails(details); | ||
| this.mongoClient.listDatabaseNames().forEach(databases::add); | ||
| Document result = this.mongoClient.getDatabase(ADMIN_DATABASE).runCommand(HELLO_COMMAND); |
There was a problem hiding this comment.
Is it possible that the user associated with the mongoClient won't be able to see the admin database? If so, I think this will fail. Perhaps admin should be used only if it's in the list returned from listDatabaseNames()? If it's not present, the first database in the list could be used instead.
There was a problem hiding this comment.
Thanks, good catch. I updated both the blocking and reactive health indicators to choose admin only when it is visible in listDatabaseNames(), otherwise they fall back to the first visible database (or admin only if the list is empty). I also added sync and reactive regression tests for the non-admin-visible case. Pushed as bc374ae.
Signed-off-by: seonwooj0810 <seonwooj0810@gmail.com>
60649ac to
bc374ae
Compare
Fixes gh-50727
Problem
MongoHealthIndicatorandMongoReactiveHealthIndicatorrun thehellocommand against every database returned bylistDatabaseNames(). For the reactive indicator the per-database commands are issued in parallel viaflatMap, so on each health check a deployment with many databases reachable through the connection opens roughly one connection per database. As reported in gh-50727, this caused a large increase in connection usage after upgrading to Spring Boot 4 (e.g. ~200 → ~1300 connections across a fleet of services that share a Mongo user and therefore see many databases).Fix
hello(formerlyisMaster) is a server-level command whose response (includingmaxWireVersion) is independent of the database it is addressed to, so there is no need to run it more than once. This change runs it a single time against theadmindatabase, which restores the single-command behavior of the previous Spring Data based implementation while keeping the current Spring-Data-free indicator.The reported health details are unchanged: both indicators still report
databases(via a singlelistDatabaseNames()call) andmaxWireVersion.I kept the
databasesdetail because it is asserted by the existing*IntegrationTests. If the team would prefer to drop it and report onlymaxWireVersion(matching the 3.x output exactly), I'm happy to update the PR.Test evidence
./gradlew :module:spring-boot-mongodb:test :module:spring-boot-mongodb:checkstyleMain :module:spring-boot-mongodb:checkstyleTest :module:spring-boot-mongodb:checkFormatMain :module:spring-boot-mongodb:checkFormatTest— all pass.compileDockerTestJavaalso passes (the Testcontainers-based*IntegrationTestswere not run here as Docker was unavailable, but they compile and their existing assertions ondatabases/maxWireVersionstill hold). The unit tests were updated to verify thehellocommand is only addressed toadminand never to a listed database.Verification done: confirmed both
.javaindicators still contained the per-databaserunCommandloop on currentmain; no in-flight PR (searched open PRs forMongoHealthIndicator/MongoReactiveHealthIndicator/mongo health/50727); no claim comments on the issue; issue carriestype: regression(notstatus: waiting-for-triage); compared against the Spring Boot 3.5.xMongoReactiveHealthIndicatorto confirm the single-command intent.