Spring Data MongoDB没有关闭MongoDB连接

6
我正在为我的Web应用程序使用spring-webmvc框架和spring-data-mongodb(1.7.0.RELEASE)。我正在使用mongoRepository进行基本的CRUD功能,但是我没有在代码中关闭mongo连接,因为我认为spring-data-mongodb会自动关闭。 但它不断地打开新连接并且不关闭它们。这些过多的连接导致我的应用程序崩溃,并且我必须不断重启Tomcat(每天两次)来解决此问题。
注意:Spring应用程序和mongod在同一台服务器上。 这是崩溃后的日志。
    2015-07-17T01:31:20.068-0400 I NETWORK  [conn3645] end connection 127.0.0.1:55302 (2583 connections now open)
    2015-07-17T01:31:20.071-0400 I NETWORK  [conn1713] end connection 127.0.0.1:48174 (2352 connections now open)
    2015-07-17T01:31:20.072-0400 I NETWORK  [conn2250] end connection 127.0.0.1:51017 (2325 connections now open)
    2015-07-17T01:31:20.072-0400 I NETWORK  [conn2149] end connection 127.0.0.1:50670 (2320 connections now open)

重新启动Tomcat后的日志如下:

2015-07-17T01:31:29.994-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:53599 #3984 (1 connection now open)
2015-07-17T01:31:33.263-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:53740 #3985 (2 connections now open)
2015-07-17T01:31:33.580-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:53750 #3986 (3 connections now open)
2015-07-17T02:10:06.477-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:50086 #3987 (4 connections now open)
2015-07-17T02:10:06.590-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:50090 #3988 (5 connections now open)
2015-07-17T02:10:11.682-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:50242 #3989 (6 connections now open)
2015-07-17T02:10:11.780-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:50244 #3990 (7 connections now open)
2015-07-17T02:10:12.545-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:50255 #3991 (8 connections now open)
2015-07-17T02:10:12.605-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:50258 #3992 (9 connections now open)
2015-07-17T02:10:13.413-0400 I NETWORK  [initandlisten] connection accepted from 127.0.0.1:50299 #3993 (10 connections now open)

每当我向应用程序发送请求时,IT技术会增加。

这是崩溃后Tomcat日志记录 -

Jul 16, 2015 3:59:57 PM org.apache.tomcat.util.net.JIoEndpoint$Acceptor run
SEVERE: Socket accept failed
java.net.SocketException: Too many open files
    at java.net.PlainSocketImpl.socketAccept(Native Method)
    at java.net.AbstractPlainSocketImpl.accept(AbstractPlainSocketImpl.java:404)
    at java.net.ServerSocket.implAccept(ServerSocket.java:545)
    at java.net.ServerSocket.accept(ServerSocket.java:513)
    at org.apache.tomcat.util.net.DefaultServerSocketFactory.acceptSocket(DefaultServerSocketFactory.java:60)
    at org.apache.tomcat.util.net.JIoEndpoint$Acceptor.run(JIoEndpoint.java:222)
    at java.lang.Thread.null(Unknown Source)

这是一个开发服务器,每分钟的流量少于10个请求。

请问有人能建议我如何关闭这些连接吗?


你看过下面的问题了吗?http://stackoverflow.com/questions/13721115/what-is-the-correct-way-to-close-the-mongo-connection-using-spring-mongo - Ravindra babu
4个回答

4

MongoClient维护连接池,您只需使用MongoClient打开一次数据库连接,并在应用程序中重复使用它,因为建立新的TCP连接在时间和内存方面都很昂贵,这就是为什么您需要重复使用连接。此外,新连接将导致在MongoDB上创建一个新的线程,从而在Db上使用内存。

  • 请注意,在connectToMongo方法中存在竞争条件。您需要同步访问该方法,以确保最多只创建一个MongoClient实例。

3

Spring不会自动关闭连接。只有在上下文被关闭时,它才会关闭连接。

请查看这篇文章

最好按照这篇文章的方式配置Mongo选项。

但是,您需要根据应用程序流量微调这些值。

<beans>

  <mongo:mongo host="localhost" port="27017">
    <mongo:options connections-per-host="8"
                   threads-allowed-to-block-for-connection-multiplier="4"
                   connect-timeout="1000"
                   max-wait-time="1500}"
                   auto-connect-retry="true"
                   socket-keep-alive="true"
                   socket-timeout="1500"
                   slave-ok="true"
                   write-number="1"
                   write-timeout="0"
                   write-fsync="true"/>
  </mongo:mongo/>

</beans>

2
我之前因为使用new而非自动装配(autowiring)也遇到过相似的问题,如果你正在手动操作,请务必使用关闭连接的方法。
 mongoDBObject.getDB().getMongo().close().

在我的情况下,它是自动连接的。 - vivex

1

Spring-data-mongodb使用连接池来重用连接,因此它不会关闭连接,并在下次重用它。为此,您需要创建mongo类的单例实例。

如果您是使用Spring IOC(使用@AutoWired)创建Mono-repository实例,则它可以正常工作,因为它返回单例实例,因此每次只有少量连接。但是,我没有使用@Autowired创建存储库实例,而是通过new方法手动创建它们,因此每次都会给我一个新的mongo()实例。新的mongo实例意味着对db的新连接。而且没有办法关闭它。这就是为什么我有太多打开的连接的原因。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接