Mongo打开了太多连接

我试图在Java循环中向MongoDB写入大量数据。 我根据打开的连接数得到错误。

我的理论是,由于MongoDB不是事务性的,因此可以同时打开许多连接。 然而,Java代码也能够非常快地循环,在一定时间之后循环迭代的次数开始超过可用连接的数量并且Mongo碰到墙。

我的代码看起来像这样。 我已经看到它建议不要做m.close()但是你只是更快地得到错误。

 public static void upsert(){ Mongo m = null; DB db = null; try { m = new Mongo("localhost"); db = m.getDB("sempedia"); } catch (UnknownHostException e1) { e1.printStackTrace(); } catch (MongoException e1) { e1.printStackTrace(); } // create documents // I am doing an upsert - hence the doc, doc DBCollection triples; try { triples = db.getCollection("triples"); triples.update(doc,doc,true,false); } catch (MongoException e) { e.printStackTrace(); } m.close(); } 

在我的java控制台中,我收到此错误:

警告:使用0 java.net.SocketException确定maxBSON大小的exception:连接重置

并且mongodb给出了这个错误:

星期二10月25日22:31:39 [initandlisten]连接被拒绝,因为太多的开放连接:204中的204

处理这个问题最优雅的方法是什么?

您正在为每个单独的操作创建Mongo类的实例。 这不起作用,因为每个实例将创建并保持至少一个连接(但默认情况下为10),并且只有在Java GC清理Mongo实例或调用close()时才会删除这些连接。

问题是,在这两种情况下,即使使用单个线程,您创建它们的速度也比它们关闭的速度快。 这将匆忙耗尽最大量的连接。 正确的解决方法是使用单例模式保留一个Mongo实例(Mongo.Holder为此提供了function,请尝试使用Mongo.Holder.connect(..))。 快速“修复”是增加计算机上的文件描述符限制,因此最大连接数量要高得多,但显然最终可能达到相同的限制。 您可以使用(在shell中)检查当前最大值:

 db.serverStatus().connections 

TL; DR:将Mongo实例视为单例并使它们尽可能长寿,并且你是金色的。 使用静态方法getInstance()实现一个MongoFactory,返回一个延迟创建的实例就可以了。 祝你好运。

每次通过您的方法时,您都会创建一个新的MongoClient。

我也遇到了这个问题,但我解决了它制作checkConnection函数:

 private static DBCollection checkConnection(String collection) throws UnknownHostException{ if(db == null){ db = (new MongoClient(host, port)).getDB(database); } return db.getCollection(collection); } 

在实例化变量的顶部,请执行以下操作:

 private static DB db = null; private static String database = ""; private static String host = "localhost"; //<--- usually localhost private static int port = 27017; //<---- usually 27017, but you can change it. 

然后当你创建一个方法时,让它像这样:

  public  someFunction() throws UnknownHostException{ DBCollection dbCollection = checkConnection("triples"); //<--- can be "triples" //or whatever collection you want  

这种方法有一些优点:

 - Code reusability, you won't have to write the same thing at every method - Readability, which programmer doesn't understand this: DBCollection dbCollection = checkConnection("triples"); - ONLY ONE CONNECTION WHICH YOU RE-USE (this doesn't affect data not being synced) 

希望我帮忙

Interesting Posts