我遇到了在Java servlet上使用Mongo DB的问题。
我的servlet有许多方法(~20)访问数据库以检索和添加数据。一个非常简短的例子:
public static String getSomething(String s) {
String json = "[]";
JSONArray jsonArray = new JSONArray();
DBCollection table;
try {
Mongo mongo = new Mongo("localhost", 27017);
DB db = mongo.getDB( "myDb" );
BasicDBObject quoteQuery = new BasicDBObject("abc", abc);
DBCursor cursor = table.find(quoteQuery);
try {
while(cursor.hasNext()) {
jsonArray.put(cursor.next());
}
} finally {
cursor.close();
}
// ...
现在问题是当这个Java servlet部署在linux服务器上时,它可以正常工作10天左右。
之后它崩溃了。
当我转到我的var / log目录中的mongodb.log时,我得到以下重复输出:
“连接被拒绝,因为开放连接太多”
我不确定现在在哪里编辑或如何处理这个问题。我试图增加服务器中打开连接的限制,但仍然有相同的结果。
有什么建议吗?
答案 0 :(得分:11)
来自API文档:http://api.mongodb.org/java/2.11.3/
public class Mongo extends Object
具有内部连接池的数据库连接。 对于大多数应用程序,您应该为整个JVM配备一个Mongo实例。
答案 1 :(得分:3)
你应该非常谨慎地创建Mongo对象,理想情况下,每个类加载器在任何时候都只能创建一个。要减少Mongo对象的数量,可以在servlet的init方法中创建它,并在每次调用时重用该实例。
编辑:看看我们的代码,我们使用经典的单例类管理Mongo实例(并且总是使用该类的Mongo
方法获取getInstance()
),因为如果你有多个servlet /仅使用init()
的应用中的入口点仍将为每个servlet生成一个实例,但仍不满足@FredClose引用的手册部分
答案 2 :(得分:1)
您可以创建一次mongo对象,而不是在每次getSomething调用时创建它。
public SomeClass{
static Mongo mongo = new Mongo("localhost", 27017);
static DB db = mongo.getDB( "myDb" );
public static String getSomething(String s) {
String json = "[]";
JSONArray jsonArray = new JSONArray();
DBCollection table;
try {
BasicDBObject quoteQuery = new BasicDBObject("abc", abc);
DBCursor cursor = table.find(quoteQuery);
while(cursor.hasNext()) {
jsonArray.put(cursor.next());
}
}
实际上,理想情况是根本不使用静态访问,而是从中央控制器注入数据库对象。
答案 3 :(得分:1)
您正在MongoDB中创建连接,但您没有关闭连接。对于任何数据库,关闭连接非常重要,否则它将达到其最大限制,并且您将无法正确执行程序。以下代码将有助于我希望:
public static String getSomething(String s) {
String json = "[]";
JSONArray jsonArray = new JSONArray();
try {
MongoClient mongoClient = new MongoClient("localhost", 27017);
DB db = mongoClient.getDB("myDb");
DBCollection collection = db.getCollection("NAME OF YOUR COLLECTION");
BasicDBObject quoteQuery = new BasicDBObject("abc", "VARIABLE THAT YOU WANT TO FIND");
DBCursor cursor = collection.find(quoteQuery);
try {
while (cursor.hasNext()) {
jsonArray.put(cursor.next());
}
} finally {
cursor.close();
}
mongoClient.close();
} catch (Exception e) {
}
return jsonArray.toString();
}
在此代码中,'MongoClient'在其用途结束后关闭。
答案 4 :(得分:0)
Arun Gupta @arungupta
新示例演示了如何在#JavaEE7应用程序中使用Mongo:New sample to show basic usage of Mongo in a Java EE application
答案 5 :(得分:-1)
按照上面提到的问题,它就像你为每个请求创建Mongo对象。我建议在整个应用程序中使用单个Object。这样你就可以找到" MongoClient和连接池&#34 ;。 MongoClient将自动为您处理连接池。
mongoClient =新的MongoClient(URI,connectionOptions);
此处mongoClient对象保存您的连接池,并根据需要为您的应用提供连接。当应用程序在整个应用程序中初始化并重复使用此对象以与数据库通信时,您应该努力创建此对象。最常见的连接池问题我们看到来自创建MongoClient对象的应用程序的结果太频繁,有时在每个数据库请求上。如果这样做,您将不会使用连接池,因为每个MongoClient对象都维护一个单独的池,该池不会被您的应用程序重用。