MongoDB:ReadPreferenceServerSelector 没有选择服务器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/29718933/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
MongoDB: No server chosen by ReadPreferenceServerSelector
提问by ahwyX100
Recently I am using mongodb java async driver which is newly released. I am writing some simple test codes, which are:
最近我正在使用新发布的 mongodb java 异步驱动程序。我正在编写一些简单的测试代码,它们是:
MongoClient mongoClient = MongoClients.create();
System.out.println("database has been connected!");
SingleResultCallback<Void> callbackWhenFinished = new SingleResultCallback<Void>() {
@Override
public void onResult(final Void result, final Throwable t) {
System.out.println("Operation Finished!");
}
};
mongoClient.listDatabaseNames().forEach(new Block<String>() {
@Override
public void apply(final String s) {
System.out.println(s);
}
}, callbackWhenFinished);
however, the callback function is not called, the console output is:
但是,没有调用回调函数,控制台输出是:
April 18, 2015 10:50:27 afternoon com.mongodb.diagnostics.logging.JULLogger log message: Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
database has been connected!April 18, 2015 10:50:28 afternoon com.mongodb.diagnostics.logging.JULLogger log message: No server chosen by ReadPreferenceServerSelector{readPreference=primary} from cluster description ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, all=[ServerDescription{address=localhost:27017, type=UNKNOWN, state=CONNECTING}]}. Waiting for 30000 ms before timing out
2015 年 4 月 18 日 10:50:27 下午 com.mongodb.diagnostics.logging.JULLogger 日志消息:Cluster created with settings {hosts=[localhost:27017], mode=SINGLE, requiredClusterType=UNKNOWN, serverSelectionTimeout='30000 ms', maxWaitQueueSize=500}
数据库已连接!2015 年 4 月 18 日 10:50:28 下午 com.mongodb.diagnostics.logging.JULLogger 日志消息:ReadPreferenceServerSelector{readPreference=primary}没有选择服务器来自集群描述 ClusterDescription{type=UNKNOWN, connectionMode=SINGLE, all=[ServerDescription{地址=本地主机:27017,类型=未知,状态=连接}]}。超时前等待 30000 毫秒
So you can see there is no callback function called. Anyone knows why?
所以你可以看到没有调用回调函数。有谁知道为什么?
回答by Ross
The short answer is your callback will be called eventually.
简短的回答是您的回调最终会被调用。
For the long answer, lets work through your code:
对于长答案,让我们来看看你的代码:
MongoClient mongoClient = MongoClients.create();
System.out.println("database has been connected!");
MongoClient
doesn't block waiting for a connection to MongoDB in the background the internal connection pool is trying to connect. From your logs I can see you have the default serverSelectionTimeout
of 30000ms.
MongoClient
不会阻止在内部连接池尝试连接的后台等待连接到 MongoDB。从您的日志中,我可以看到您的默认serverSelectionTimeout
值为 30000 毫秒。
Next step you do a println
which output immediately so "database has been connected!" gets printed regardless.
下一步您println
立即执行which 输出,以便“数据库已连接!” 无论如何都会打印出来。
Finally, you call listDatabaseNames()
but what's not clear is if any waits for the callback to be called. If you add a latch then await the response then you will see that the callback is called eg:
最后,您调用listDatabaseNames()
但不清楚的是是否有任何等待调用回调。如果你添加一个锁存器然后等待响应,那么你会看到回调被调用,例如:
System.out.println("======= Start =======");
MongoClient mongoClient = MongoClients.create();
final CountDownLatch latch = new CountDownLatch(1);
SingleResultCallback<Void> callbackWhenFinished = new SingleResultCallback<Void>() {
@Override
public void onResult(final Void result, final Throwable t) {
System.out.println("Operation Finished!");
if (t != null) {
System.out.println("listDatabaseNames() errored: " + t.getMessage());
}
latch.countDown();
}
};
mongoClient.listDatabaseNames().forEach(new Block<String>() {
@Override
public void apply(final String s) {
System.out.println(s);
}
}, callbackWhenFinished);
latch.await();
// close resources
mongoClient.close();
System.out.println("======= Finish =======");
Now using the latch we await()
until the callback has been called, now we should see one of two things happen:
现在使用锁存器,await()
直到回调被调用,现在我们应该看到以下两种情况之一发生:
There is no MongoDB available. It will eventually call the callback and print that there was an error. It will wait until the
serverSelectionTimeout
times out.There is a MongoDB available. It will eventually connect, for each database it will apply the
Block
and print out the database name and then finally it will call the callback signalling it has finished.
没有可用的 MongoDB。它最终会调用回调并打印出有错误。它会等到
serverSelectionTimeout
超时。有一个 MongoDB 可用。它将最终连接,对于每个数据库,它将应用
Block
并打印出数据库名称,然后最终将调用回调信号通知它已完成。
回答by fegyi001
I think you should close the MongoClient object every time in a finally clause. For me the same problem occured, and when I closed the connection in the command line I saw that a LOT of connections were open.
我认为您应该每次在 finally 子句中关闭 MongoClient 对象。对我来说,发生了同样的问题,当我在命令行中关闭连接时,我看到很多连接都打开了。
Try something like this (I use mongodb 3.0.7 and mongo-java-driver 3.1.0):
尝试这样的事情(我使用 mongodb 3.0.7 和 mongo-java-driver 3.1.0):
package com.mkyong.core;
import org.bson.Document;
import org.junit.Test;
import com.mongodb.Block;
import com.mongodb.MongoClient;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoDatabase;
/**
* Unit test for simple App.
*/
public class AppTest {
@Test
public void firstTest() throws Exception {
MongoClient mongoClient = null;
try {
mongoClient = new MongoClient("127.0.0.1", 27017);
MongoDatabase db = mongoClient.getDatabase("census");
FindIterable<Document> iterable = db.getCollection("states").find();
iterable.forEach(new Block<Document>() {
@Override
public void apply(final Document document) {
System.out.println(document);
}
});
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
mongoClient.close();
} catch (Exception e2) {
}
}
}
}
With this, I could use my connection with no problem.
有了这个,我可以毫无问题地使用我的连接。