在Spring Data MongoDB中处理读取超时的最佳方法

pde*_*eva 8 java spring mongodb spring-data spring-data-mongodb

因此我们不时会看到以下异常:

java.net.SocketTimeoutException: Read timed out
at java.net.SocketInputStream.socketRead0(Native Method)
at java.net.SocketInputStream.read(SocketInputStream.java:150)
at java.net.SocketInputStream.read(SocketInputStream.java:121)
at java.io.BufferedInputStream.fill(BufferedInputStream.java:246)
at java.io.BufferedInputStream.read1(BufferedInputStream.java:286)
at java.io.BufferedInputStream.read(BufferedInputStream.java:345)
at org.bson.io.Bits.readFully(Bits.java:48)
at org.bson.io.Bits.readFully(Bits.java:35)
at org.bson.io.Bits.readFully(Bits.java:30)
at com.mongodb.Response.<init>(Response.java:42)
at com.mongodb.DBPort$1.execute(DBPort.java:141)
at com.mongodb.DBPort$1.execute(DBPort.java:135)
at com.mongodb.DBPort.doOperation(DBPort.java:164)
at com.mongodb.DBPort.call(DBPort.java:135)
at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:292)
at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:271)
at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:84)
at com.mongodb.DBCollectionImpl.find(DBCollectionImpl.java:66)
at com.mongodb.DBCollection.findOne(DBCollection.java:870)
at com.mongodb.DBCollection.findOne(DBCollection.java:844)
at com.mongodb.DBCollection.findOne(DBCollection.java:790)
at org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java:2000)
Run Code Online (Sandbox Code Playgroud)

什么是在代码中处理和恢复这些的最佳方法?我们是否需要围绕每一个mongodb电话进行"重试"?

kam*_*oor 5

您可以使用MongoClientOptions对象设置不同的可选连接参数.您正在设置心跳频率以确保驱动程序重试连接.同时设置套接字超时以确保它不会持续太长时间.

  1. MinHeartbeatFrequency:如果驱动程序必须经常重新检查服务器的可用性,它将至少在上一次检查后等待很长时间,以避免浪费精力.默认值为10毫秒.
  2. HeartbeatSocketTimeout:心跳检查超时
  3. SocketTimeout:超时连接

参考API

为避免过多的代码重复,您可以选择遵循下面给出的某种模式.基本思想是避免在项目中随处可见的任何数据库连接相关配置.

/**
 * This class is an abstraction for all mongo connection config
 **/
 @Component
 public class MongoConnection{

    MongoClient mongoClient = null;

    ...

   @PostConstruct
   public void init() throws Exception {
            // Please watch out for deprecated methods in new version of driver.
            mongoClient = new MongoClient(new ServerAddress(url, port), 
                            MongoClientOptions.builder()
                            .socketTimeout(3000)
                            .minHeartbeatFrequency(25)
                            .heartbeatSocketTimeout(3000)
                            .build());
            mongoDb = mongoClient.getDB(db);
        .....   
   }

   public DBCollection getCollection(String name) {
        return mongoDb.getCollection(name);
    }
   }
Run Code Online (Sandbox Code Playgroud)

现在您可以在DAO-s中使用MongoConnection

@Repository
public class ExampleDao{

  @Autowired
  MongoConnection mongoConnection;

  public void insert(BasicDBObject document) {
     mongoConnection.getCollection("example").insert(document);
  }  
}
Run Code Online (Sandbox Code Playgroud)

您还可以在MongoConnection中实现所有数据库操作,以全面介绍一些常用功能.例如,为所有"插入"添加日志记录


mav*_*azy 0

处理重试的众多选项之一是 Spring retry 项目

https://github.com/spring-projects/spring-retry

它为 Spring 应用程序提供声明性重试支持。这基本上是 Spring 对这个问题的回答。它用于 Spring Batch、Spring Integration、Spring for Apache Hadoop(等等)。