SpringBoot使用MongoDB异常问题

一 环境介绍

  • SpringBoot1.5.13.RELEASE(本地)
  • Spring Data MongoDB
  • Java 8
  • MongoDB(青云)

二 问题描述

  • 使用Studio3T或者Compass等MongoDB的GUI工具连接MongoDB不操作一段时间,就会掉线。但重连速度很快。
  • 使用Java的Mongo连接驱动,也是一段时间不操作,再去操作会出现异常(SocketTimeout,能发不能收;连接没有断),同样也是重连速度很快。
# java日志太长,省略一部分
14:03:47.629 [http-nio-8081-exec-5] ERROR c.d.o.c.TestController - Timeout while receiving message; nested exception is com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message
org.springframework.data.mongodb.UncategorizedMongoDbException: Timeout while receiving message; nested exception is com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving message
......
Caused by: com.mongodb.MongoSocketReadTimeoutException: Timeout while receiving 
message
......
Caused by: java.net.SocketTimeoutException: Read timed out

三 搜索原因

连接被对方丢弃

  • MongoDB始终是部署操作系统上,而对于大型公司提供MongoDB的服务会经过层层防火墙、代理服务和负载均衡器。它们把Java保持的连接踢掉了(状态变成CLOSE_WAIT,只能发数据但无法再收到)。
  • 于是提了工单问青云情况,他们反馈就是如果从外网连接需要通过VPN才不会掉线,经过测试将应用部署在青云服务器上的确没有问题。
  • 如果是自己的服务器搭建mongdb可以参考:https://stackoverflow.com/questions/35597930/sockettimeout-with-opened-connection-in-mongodb 该链接解决。(设置:sudo sysctl -w net.ipv4.tcp_keepalive_time=

参考:https://segmentfault.com/q/1010000009595664/a-1020000009596082

参考:https://blogs.msdn.microsoft.com/avkashchauhan/2011/11/12/windows-azure-load-balancer-timeout-details/

  • 同样的情况也出现在了微软的Azure Load Balancer。

参考:https://blogs.msdn.microsoft.com/avkashchauhan/2011/11/12/windows-azure-load-balancer-timeout-details/

四 解决方案

(1)Studio 3T的掉线问题

  • 设置 Max connection idle time(连接池中某个连接的空闲时间超过该值,将丢弃该连接并重新新建立一个连接)

参考:https://studio3t.com/knowledge-base/articles/prevent-mongodb-connection-timeout/

(2)SpringBoot中如何设置?

  • 方案1:
@Configuration
public class MongoDbSettings {

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

}
  • 方案2:程序员DD的spring-boot-starter-mongodb-plus

参考:http://blog.didispace.com/springbootmongodb-plus/

(3)应用放到防火墙里面

五 Spring Data Mongo与mongodb-driver的关系

  • SpringBoot启动日志中的一句(由SimpleServerCluster打印的)
14:36:55.672 [restartedMain] INFO  org.mongodb.driver.cluster - Cluster created with settings {hosts=[mongodb的IP地址:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
# 这句日志只能显示简短的启动信息,不能作为你修改了配置后是否生效的判断依据。

  • mongodb-driver相关的类
    • MongoClientOptions:MongoDB连接的配置类
    • MongoClient(继承Mongo):带有连接池的Mongo客户端
    • Mongo:带有连接池的数据库连接
    • DefaultClusterFactory:集群实现的默认工厂
    • SimpleServerCluster:真正创建的集群Server连接
    • DB:MongoDB集群中逻辑数据库的线程安全客户端视图,用于实际操作MongoDB的类。
  • Spring Data Mongo相关的类
    • MongoOperations:指定一组基本MongoDB操作的接口。(Spring Data Mongo)
    • MongoTemplate(实现MongoOperations):MongoOperations的首要实现类(Spring Data Mongo)
    • SimpleMongoDbFactory:一个从Mongo实例创建DB实例的工厂类。(Spring Data Mongo)

注意:篇幅有限,加上比较复杂,以后再详细研究一下。

posted @ 2018-09-19 15:21 月下小魔王 阅读(...) 评论(...) 编辑 收藏