Set Mongo Timeout in Spring Boot

后端 未结 7 1122
失恋的感觉
失恋的感觉 2020-12-30 10:21

I am using spring boot web application which connects to mongo db which is working out of the box. I just use the following properties:

spring.data.mongodb.h         


        
相关标签:
7条回答
  • 2020-12-30 10:53

    MongoClientOptions is a class which has the required properties.

    Programmatically If you have configured your MongoDB programmatically, then below is the code snippet to help you out.

    DB mongoDb;
    
    MongoClient mongoClient = new MongoClient(new ServerAddress(url, port), 
                                MongoClientOptions.builder()
                                .socketTimeout(3000)
                                .minHeartbeatFrequency(25)
                                .heartbeatSocketTimeout(3000)
                                .build());
    mongoDb = mongoClient.getDB(dbname);
    

    XML Configuration - Advanced

    <beans>
    
      <mongo:mongo host="localhost" port="27017">
        <mongo:options connections-per-host="8"
                       threads-allowed-to-block-for-connection-multiplier="4"
                       connect-timeout="1000"
                       max-wait-time="1500}"
                       auto-connect-retry="true"
                       socket-keep-alive="true"
                       socket-timeout="1500"
                       slave-ok="true"
                       write-number="1"
                       write-timeout="0"
                       write-fsync="true"/>
      </mongo:mongo/>
    
    </beans>
    

    Also refer here for complete documentation.

    0 讨论(0)
  • 2020-12-30 10:55

    The question is old but for all those who have problems with Mongo DB JAVA driver timeouts : set the maxConnectionIdleTime property.

    Example Spring Boot :

    import com.mongodb.MongoClient;
    import com.mongodb.MongoClientOptions;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
    import org.springframework.boot.autoconfigure.mongo.MongoProperties;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.core.env.Environment;
    
    import javax.annotation.PreDestroy;
    import java.net.UnknownHostException;
    
    @Configuration
    @ConditionalOnClass(MongoClient.class)
    @EnableConfigurationProperties(MongoProperties.class)
    @ConditionalOnMissingBean(type = "org.springframework.data.mongodb.MongoDbFactory")
    public class MongoAutoConfiguration {
        @Autowired
        private MongoProperties properties;
    
        @Autowired(required = false)
        private MongoClientOptions options;
    
        @Autowired
        private Environment environment;
    
        private MongoClient mongo;
    
        @PreDestroy
        public void close() {
            if (this.mongo != null) {
                this.mongo.close();
            }
        }
    
        @Bean
        @ConditionalOnMissingBean
        public MongoClient mongo() throws UnknownHostException {
            this.options = options.builder().maxConnectionIdleTime(1000 * 60 * 4).build();
            this.mongo = this.properties.createMongoClient(this.options, this.environment);
            return this.mongo;
        }
    }
    

    A very useful link here : Java DriverJAVA-2535 com.mongodb.MongoSocketWriteException ......

    0 讨论(0)
  • 2020-12-30 10:57

    For Spring Data with Reactive MongoDb:

    My case was a bit different (I had closing connections - which throws "Caused by: java.lang.IllegalStateException: state should be: open")

    But You can use this with your case.

    application.yml:

    spring.data.mongodb:
      host: localhost
      database: myDb
      port: 27017
      username: admin
      password: test
    

    If Your implementation use MongoReactiveAutoConfiguration for bean creation, then You can configure it with this bean:

    @Bean
    public MongoClientSettings mongoClientSettings() {
        final MongoClientSettings clientSettings = MongoClientSettings.builder()
                .retryWrites(true)
                .applyToConnectionPoolSettings((ConnectionPoolSettings.Builder builder) -> {
                    builder.maxSize(300) //connections count
                            .minSize(100)
                            .maxConnectionLifeTime(0, TimeUnit.MILLISECONDS)
                            .maxConnectionIdleTime(0, TimeUnit.MILLISECONDS)
                            .maxWaitTime(5000, TimeUnit.MILLISECONDS)
                            .maxWaitQueueSize(5000);
                })
                .applyToSocketSettings(builder -> {
                    builder.connectTimeout(2000, TimeUnit.MILLISECONDS);
                })
                .applicationName("app")
                .build();
    
        return clientSettings;
    }
    
    0 讨论(0)
  • 2020-12-30 11:00

    To follow your theme, this would be the best to answer your question. Looks like you would like to set a timeout in your application.properties file.

    In order to do so:

    Instead of

    spring.data.mongodb.host=myHost
    spring.data.mongodb.port=27017
    spring.data.mongodb.database=myDatabase
    
    spring.data.mongodb.username=myUser
    spring.data.mongodb.password=myPassword
    

    Try this

    spring.data.mongodb.uri=mongodb://myUser:myPassword@myHost:27017,myHost:27017/myDatabase?serverSelectionTimeoutMS=2000&connectTimeoutMS=2000
    spring.data.mongodb.database=myDatabase
    spring.data.mongo.repositories.enabled=true
    

    Modify time in milliseconds to desired time.

    0 讨论(0)
  • 2020-12-30 11:01

    The question was specifically for Spring boot. I am using the following approach which works well, please suggest if there is a way not to use new and use Spring for configuring it.

     import java.util.ArrayList;
     import java.util.List;
     import org.springframework.beans.factory.annotation.Value;
     import org.springframework.context.annotation.Bean;
     import org.springframework.context.annotation.Configuration;
     import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
     import org.springframework.data.mongodb.core.mapping.MongoMappingContext;
     import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
     import com.mongodb.Mongo;
     import com.mongodb.MongoClient;
     import com.mongodb.MongoClientOptions;
     import com.mongodb.MongoCredential;
     import com.mongodb.ServerAddress;
    
     @Configuration
     @EnableMongoRepositories("com.myapp.repository")
     public class SpringMongoConfig extends AbstractMongoConfiguration {
    
    @Value("${myapp.mongodb.host}")
    private String host;
    
    @Value("${myapp.mongodb.port}")
    private int port;
    
    @Value("${myapp.mongodb.database}")
    private String mongoDB;
    
    @Value("${myapp.mongodb.userName}")
    private String userName;
    
    @Value("${myapp.mongodb.password}")
    private String password;
    
    @Value("${myapp.mongodb.socketTimeoutMS}")
    private int socketTimeout;
    
    @Value("${myapp.mongodb.connectionTimeoutMS}")
    private int connectionTimeout;
    
    @Override
    public MongoMappingContext mongoMappingContext() throws ClassNotFoundException {
    return super.mongoMappingContext();
    }
    
    @Override
    @Bean
    public Mongo mongo() throws Exception {
    
    List<ServerAddress> servers = new ArrayList<ServerAddress>();
    servers.add(new ServerAddress(host, port));
    
    List<MongoCredential> creds = new ArrayList<MongoCredential>();
    creds.add(MongoCredential.createCredential(userName, mongoDB, password.toCharArray()));
    
    MongoClientOptions builder = MongoClientOptions.builder().socketTimeout(socketTimeout).connectTimeout(connectionTimeout).build();
    
    return new MongoClient(servers, creds, builder);
    }
    
    @Override
    protected String getDatabaseName() {
    return mongoDB;
    }
    }
    
    0 讨论(0)
  • 2020-12-30 11:04

    I found the following document with a possible solution.

    https://www.programmersought.com/article/1927319190/

    It mentions the following:

    spring.data.mongodb.address=172.16.250.234:27017,172.16.250.239:27017,172.16.250.240:27017
    spring.data.mongodb.replica-set=rs0
    spring.data.mongodb.database=test
    spring.data.mongodb.username=admin
    spring.data.mongodb.password=admin
    
    # Configure spring.data.mongodbDB Pool
    spring.data.mongodb.min-connections-per-host=10
    spring.data.mongodb.max-connections-per-host=100
    spring.data.mongodb.threads-allowed-to-block-for-connection-multiplier=5
    spring.data.mongodb.server-selection-timeout=30000
    spring.data.mongodb.max-wait-time=120000
    spring.data.mongodb.max-connection-idel-time=0
    spring.data.mongodb.max-connection-life-time=0
    spring.data.mongodb.connect-timeout=10000
    spring.data.mongodb.socket-timeout=0
    spring.data.mongodb.socket-keep-alive=false
    spring.data.mongodb.ssl-enabled=false
    spring.data.mongodb.ssl-invalid-host-name-allowed=false
    spring.data.mongodb.always-use-m-beans=false
    spring.data.mongodb.heartbeat-socket-timeout=20000
    spring.data.mongodb.heartbeat-connect-timeout=20000
    spring.data.mongodb.min-heartbeat-frequency=500
    spring.data.mongodb.heartbeat-frequency=10000
    spring.data.mongodb.local-threshold=15
    spring.data.mongodb.authentication-database=auth_dev
    

    I'm trying to test this now to make sure it is working, but it at least seems plausible.

    0 讨论(0)
提交回复
热议问题