Tag Archives: MongoDB Prematurely reached end of stream

An exception solution of mongodb prematurely reached end of stream in spring boot

MongoDB is used in the spring boot project. When MongoDB is not operated for a period of time, an exception will occur when MongoDB is operated next time. The exception is as follows:

org.springframework.data.mongodb.UncategorizedMongoDbException: Prematurely reached end of stream; nested exception is com.mongodb.MongoSocketReadException: Prematurely reached end of stream
        at org.springframework.data.mongodb.core.MongoExceptionTranslator.translateExceptionIfPossible(MongoExceptionTranslator.java: 107 )
        at org.springframework.data.mongodb.core.MongoTemplate.potentiallyConvertRuntimeException(MongoTemplate.java: 2146 )
        at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java: 1928 )
        at org.springframework.data.mongodb.core.MongoTemplate.doFindOne(MongoTemplate.java: 1736 )
        at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java: 606 )
        at org.springframework.data.mongodb.core.MongoTemplate.findOne(MongoTemplate.java: 601 )
        at com.lwli.service.impl.SessionServiceImpl.findOneSessionByCustomerIdAndStatus(SessionServiceImpl.java: 51 ) 
        at java.lang.Thread.run(Thread.java: 745 )
Caused by: com.mongodb.MongoSocketReadException: Prematurely reached end of stream
        at com.mongodb.connection.SocketStream.read(SocketStream.java: 88 )
        at com.mongodb.connection.InternalStreamConnection.receiveResponseBuffers(InternalStreamConnection.java: 494 )
        at com.mongodb.connection.InternalStreamConnection.receiveMessage(InternalStreamConnection.java: 224 )
        at com.mongodb.connection.UsageTrackingInternalConnection.receiveMessage(UsageTrackingInternalConnection.java: 96 )
        at com.mongodb.connection.DefaultConnectionPool$PooledConnection.receiveMessage(DefaultConnectionPool.java: 440 )
        at com.mongodb.connection.QueryProtocol.execute(QueryProtocol.java: 289 )
        at com.mongodb.connection.QueryProtocol.execute(QueryProtocol.java: 54 )
        at com.mongodb.connection.DefaultServer$DefaultServerProtocolExecutor.execute(DefaultServer.java: 168 )
        at com.mongodb.connection.DefaultServerConnection.executeProtocol(DefaultServerConnection.java: 289 )
        at com.mongodb.connection.DefaultServerConnection.query(DefaultServerConnection.java: 212 )
        at com.mongodb.operation.FindOperation$ 1.call(FindOperation.java:525 )
        at com.mongodb.operation.FindOperation$ 1.call(FindOperation.java:510 )
        at com.mongodb.operation.OperationHelper.withConnectionSource(OperationHelper.java: 435 )
        at com.mongodb.operation.OperationHelper.withConnection(OperationHelper.java: 408 )
        at com.mongodb.operation.FindOperation.execute(FindOperation.java: 510 )
        at com.mongodb.operation.FindOperation.execute(FindOperation.java: 81 )
        at com.mongodb.Mongo.execute(Mongo.java: 836 )
        at com.mongodb.Mongo$ 2.execute(Mongo.java:823 )
        at com.mongodb.DBCursor.initializeCursor(DBCursor.java: 870 )
        at com.mongodb.DBCursor.hasNext(DBCursor.java: 142 )
        at com.mongodb.DBCursor.one(DBCursor.java: 679 )
        at com.mongodb.DBCollection.findOne(DBCollection.java: 833 )
        at com.mongodb.DBCollection.findOne(DBCollection.java: 796 )
        at com.mongodb.DBCollection.findOne(DBCollection.java: 743 )
        at org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java: 2197 )
        at org.springframework.data.mongodb.core.MongoTemplate$FindOneCallback.doInCollection(MongoTemplate.java: 2181 )
        at org.springframework.data.mongodb.core.MongoTemplate.executeFindOneInternal(MongoTemplate.java: 1925 )
        ... 12 more

 

I searched the Internet and found that there are many reasons for this problem. The main reasons may be connection timeout, reading and writing timeout, etc., according to others’ tips, set

socketKeepAlive = true;
socketTimeout = 30000;

However, it didn’t work. When I visited MongoDB again after a period of time, abnormalities still appeared. When I searched on Google, I found an article https://studio3t.com/whats-new/how-to-prevent-your-connection-from-dropping-with-hosted-mongodb-instances/, which mentioned one point above, when When the connection is idle for a period of time, the connection is closed due to firewall or load balancing, and the client does not know that it will make an error when the client continues to use the closed connection for reading and writing.

The solution is to set the connection idle time. When this idle time is exceeded, the client actively closes the connection and re-establishes the connection when it is used next time, which can effectively avoid the problem of connection failure.

Configure the bean of MongoClientOptions in spring boot. For example, set the maximum idle time to 6000ms.

@Configuration
 public  class WechatMpConfiguration {

    @Bean
    public MongoClientOptions mongoOptions() {
         return MongoClientOptions.builder().maxConnectionIdleTime(6000 ).build();
    }
}

 

After passing the above settings, there is no Prematurely reached end of stream exception.