简体   繁体   中英

How to enable mongo connection pool monitoring with spring-data-mongodb in XML?

I am using spring-data-mongodb 1.10.12 with mongo 3.6.4. I recently upgraded from a lower version of mongo, and now my mongo connection pool monitoring is broken because there is no ConnectionPoolStatisticsMBean registered. According to the documentation for that version of mongo "JMX connection pool monitoring is disabled by default. To enable it add a com.mongodb.management.JMXConnectionPoolListener instance via MongoClientOptions"

However, in the xml schema for spring-data-mongo, the clientOptionsType does not allow setting that value, unless I am missing something. Is there any way, with spring-data-mongodb, to turn on the connection pool monitoring through xml?

Here is my xml for the mongo beans

<mongo:mongo-client id="mongo"
                    host="${mongo.hostname:#{null}}"
                    replica-set="${mongo.replica.set:#{null}}"
                    port="${mongo.port}"
                    credentials="'${mongo.username}:${mongo.password}@${mongo.auth.db.name}?uri.authMechanism=${mongo.auth.mechanism:SCRAM-SHA-1}'"
>
    <mongo:client-options connections-per-host="${mongo.connections-per-host:40}"
                          threads-allowed-to-block-for-connection-multiplier="${mongo.threads-blocked-per-connection:3}"
                          connect-timeout="${mongo.connection-timeout:10000}"
                          max-wait-time="${mongo.maxWaitTime:120000}"
                          socket-keep-alive="${mongo.socketKeepAlive:true}"
                          socket-timeout="${mongo.socketTimeout:0}"
                          read-preference="${mongo.read.preference:PRIMARY_PREFERRED}"
                          write-concern="${mongo.write.concern:ACKNOWLEDGED}"
    />
</mongo:mongo-client>

and my pom dependencies

<properties>
    <mongo-version>3.6.4</mongo-version>
    <spring-data-version>1.10.12.RELEASE</spring-data-version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.mongodb</groupId>
        <artifactId>mongo-java-driver</artifactId>
        <version>${mongo-version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-mongodb</artifactId>
        <version>${spring-data-version}</version>
    </dependency>
</dependencies>

It is true that there is no way, through the spring-data-mongodb schema, to add a connection pool listener, but the folks that maintain the repo suggested a solution which is to use a BeanPostProcessor to alter the MongoClientOptions before they are passed to the mongo client like so

@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

    if (bean instanceof MongoClientOptions) {
        return MongoClientOptions.builder((MongoClientOptions) bean)
            .addConnectionPoolListener(new JMXConnectionPoolListener()).build();
    }
    return bean;
}

Doing so successfully registered ConnectionPoolStatisticsMBeans for me

I tackled the very same challenge. In my case, originally the Spring configuration was done using XML. I have managed to combine the XML configuration with Java configuration, because the Java configuration gives you more flexibility to configure the MongoClientOptions :

@Configuration
public class MongoClientWrapper {

    @Bean
    public MongoClient mongo() 
    {
        //credentials:
        MongoCredential credential = MongoCredential.createCredential("user", "auth-db", "password".toCharArray());

        MongoClientOptions options = MongoClientOptions.builder()
                .addConnectionPoolListener(new MyConnectionPoolListener())
                .build();
        return new MongoClient(
                new ServerAddress("localhost", 27017),      //replica-set
                Arrays.asList(credential)
                ,options
                );
    }


    @Bean
    public MongoTemplate mongoTemplate()
    {
        return new MongoTemplate(mongo(), database);
    }
    ...
}

Hope this helps someone...

In my project, adding the BeanPostProcessor was useless, because the MongoClientOptions Bean was not automatically instantiate. I had to create Bean manually to add a connection pool listener in my environment:

@Bean public MongoClientOptions myMongoClientOptions() {
      return MongoClientOptions.builder().addConnectionPoolListener(new JMXConnectionPoolListener()).build();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM