• 记一次spring boot中MongoDB Prematurely reached end of stream的异常解决


      在spring boot项目中使用了mongodb,当一段时间没有操作mongodb,下次操作mongodb时就会出现异常。异常如下:

    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

      网上搜了下,这个问题原因很多,主要的原因可能有连接超时,读写超时等,按照别人的提示,设置了

    socketKeepAlive = true;
    socketTimeout = 30000;

      然而并没有效果,超过一段时间再次访问mongdb时,任然出现异常。在google搜索时,发现一篇文章https://studio3t.com/whats-new/how-to-prevent-your-connection-from-dropping-with-hosted-mongodb-instances/,上面提到了一点,当连接闲置一段时间,由于防火墙或者负载均衡的原因,导致连接被关闭,而客户端并不知道,当客户端继续使用这个关闭的连接进行读写时就会出错。

      解决办法就是设置连接闲置时间,当超过这个闲置时间客户端主动关闭连接,下次使用时重新建立连接,这样可以有效避免连接失效的问题。

      在spring boot中配置MongoClientOptions的bean。例如将最大闲置时间设为6000ms。

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

      通过上面的设置后,后面没有再出现Prematurely reached end of stream异常了。

  • 相关阅读:
    php设计模式 -- 数据映射模式
    php 守护进程 (简单)
    php 守护进程
    php rabbitmq demo
    linux 全局安装composer
    linux 安装rabbitmq
    linux php安装RabbitMq扩展
    http和tcp详解
    lnmp环境脚本自动配置
    30.输入年月日,判断它是该年的第多少天
  • 原文地址:https://www.cnblogs.com/lilinwei340/p/8325819.html
Copyright © 2020-2023  润新知