【问题标题】:Set Mongo Timeout in Spring Boot在 Spring Boot 中设置 Mongo 超时
【发布时间】:2016-08-15 12:08:15
【问题描述】:

我正在使用连接到开箱即用的 mongo db 的 Spring Boot Web 应用程序。我只使用以下属性:

spring.data.mongodb.host=myHost
spring.data.mongodb.port=27017
spring.data.mongodb.database=myDatabase
spring.data.mongo.repositories.enabled=true
spring.data.mongodb.username=myUser
spring.data.mongodb.password=myPassword

MongoDB 的默认超时为 10 秒。我想配置超时。我试着做 spring.data.mongodb.socketTimeout=2spring.data.mongodb.connectionTimeout=2

所有属性都不起作用。是我可以在属性中指定的东西,Spring 框架会处理它,还是有人可以通过声明 Bean 来举例说明。

【问题讨论】:

    标签: spring mongodb spring-boot


    【解决方案1】:

    要遵循您的主题,这将是回答您问题的最佳选择。 看起来您想在 application.properties 文件中设置超时。

    为此:

    代替

    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
    

    试试这个

    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
    

    以毫秒为单位将时间修改为所需时间。

    【讨论】:

    • spring.data.mongodb.uri 中是否有提供自动重新连接的选项?
    • @PSatishPatro 不需要,如果连接正常,它会自动重新连接。如果您使用的是 mongo 依赖项。
    • 很好@Jesse。不知道
    • @Jesse。如果我在 9 小时左右的这么多时间后尝试访问 mongodb,我会收到此错误。响应代码 - 500 响应标头 - 连接关闭。 textuploader.com/15s28
    • @PSatishPatro 您是否设置了超时限制?我建议先手动连接到 mongoDB,以确保连接正常。
    【解决方案2】:

    这将覆盖 Spring Boot 自动配置:

    @Configuration
    public class MongoDbSettings {
    
        @Bean
        public MongoClientOptions mongoOptions() {
            return MongoClientOptions.builder().socketTimeout(2000).build();
        }
    
    }
    

    【讨论】:

    • 看来这应该是不必要的。您还需要通过此 bean 设置所有其他属性,而不是使用属性和 spring 数据源为您构建 bean。
    【解决方案3】:

    对于带有响应式 MongoDb 的 Spring 数据:

    我的情况有点不同(我有关闭连接 - 抛出“Caused by: java.lang.IllegalStateException: state should be: open”)

    但你可以在你的情况下使用它。

    application.yml:

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

    如果您的实现使用 MongoReactiveAutoConfiguration 来创建 bean,那么您可以使用此 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;
    }
    

    【讨论】:

    • 这对于任何使用最新版 spring 的人来说都是正确的答案。
    【解决方案4】:

    MongoClientOptions 是一个具有所需属性的类。

    以编程方式 如果您已经以编程方式配置了 MongoDB,那么下面的代码 sn-p 可以帮助您。

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

    XML 配置 - 高级

    <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>
    

    另请参阅here 以获取完整文档。

    【讨论】:

      【解决方案5】:

      这个问题很老,但对于所有遇到 Mongo DB JAVA 驱动程序超时问题的人来说:设置 maxConnectionIdleTime 属性。

      示例 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;
          }
      }
      

      这里有一个非常有用的链接:Java DriverJAVA-2535 com.mongodb.MongoSocketWriteException ......

      【讨论】:

      • 不能在 application.properties 中作为 spring.data.maxConnectionIdleTime = 123 吗?
      • @bleh10 我没试过。
      【解决方案6】:

      这个问题专门针对 Spring Boot。我正在使用以下方法,效果很好,请建议是否有办法不使用 new 并使用 Spring 进行配置。

       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;
      }
      }
      

      【讨论】:

        【解决方案7】:

        我找到了以下文档,其中包含一个可能的解决方案。

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

        它提到了以下内容:

        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
        

        我现在正在尝试对此进行测试,以确保它可以正常工作,但至少看起来是合理的。

        【讨论】:

        • 您引用的文章还表明,它需要自定义代码来摄取这些并以编程方式将它们设置到 MongoClientOptions.Builder() 实例中。这里没有什么是自动的。 (在属性名称中使用 spring.data 前缀可能暗示了这一点,但这只是作者的选择,因此我会避免使用)。此外,当前版本的 Spring 中不再存在 MongoClientOptions。另外,将来最好先测试一下你的想法,如果可行,再发布。
        猜你喜欢
        • 1970-01-01
        • 2017-06-05
        • 2017-04-19
        • 2019-06-02
        • 2023-03-06
        • 1970-01-01
        • 2019-01-06
        • 1970-01-01
        • 2020-03-28
        相关资源
        最近更新 更多