Best way to handle read timeouts in Spring Data MongoDB

Therefore, from time to time we see such exceptions:

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) 

What is the best way to process and recover from them in code? Do we need to "repeat" all mongodb calls?

+6
source share
5 answers

You can use the MongoClientOptions object to set various optional connection parameters. You are looking at setting your heart rate to make sure you try connecting to your computer again. Also set the socket timeout so that it does not last too long.

  • MinHeartbeatFrequency: in case the driver needs to frequently check the availability of the server, it will wait at least as long as the previous check to avoid wasted effort. The default value is 10 ms.
  • HeartbeatSocketTimeout: timeout for checking heartbeat
  • SocketTimeout: connection timeout

Help API

To avoid excessive code duplication, you can optionally follow the pattern example as shown below. The basic idea is to avoid the configuration associated with connecting to a database that is littered everywhere in projects.

 /** * 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); } } 

Now you can use MongoConnection in DAO-s

 @Repository public class ExampleDao{ @Autowired MongoConnection mongoConnection; public void insert(BasicDBObject document) { mongoConnection.getCollection("example").insert(document); } } 

You can also implement all database operations inside MongoConnection to introduce some common functions in all directions. For example, add logging for all "inserts"

+5
source

One of the many repetition processing options is Spring replay project.

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

which provides declarative retry support for Spring applications. This is basically Spring's answer for this problem. It is used in Spring Batch, Spring Integration, Spring for Apache Hadoop (among others).

0
source

If you want to approach timeouts (and related) with problems not only for your MongoDB, but also for any other external links, then you should try Netflix Hystrix ( https://github.com/Netflix/Hystrix ).

This is a terrific library that blends nicely with RX and asynchronous processing, which has recently become increasingly popular.

0
source

If I'm not mistaken, I think you need to configure your properties as a timeout or so when you are trying to build a connection or just prepare them well in the connection pool. Or you can just check your network or machine and split your data requests several times to reduce the time it takes to broadcast on the network.

0
source

https://github.com/Netflix/Hystrix is your tool for handling dependencies.

0
source

Source: https://habr.com/ru/post/980676/


All Articles