我正在Eclipse中开发一个Java项目。我有一个临时服务器和一个实时服务器。这两个也有自己的mongodbs,它们运行在两个不同端口(29017和27017)上的不同服务器上。 通过Junit测试,我想将实时mongo中的数据复制到devel mongo。
最奇怪的事情:有时它会起作用,有时我会收到套接字错误。我想知道为什么mongo有时完全拒绝写插页,而在其他日子里它完美无缺。以下是mongo日志文件(代码插入的文件)和Junit测试脚本的摘录:
mongo log:
Thu Mar 14 21:01:04 [initandlisten] connection accepted from xx.xxx.xxx.183:60848 #1 (1 connection now open)
Thu Mar 14 21:01:04 [conn1] run command admin.$cmd { isMaster: 1 }
Thu Mar 14 21:01:04 [conn1] command admin.$cmd command: { isMaster: 1 } ntoreturn:1 keyUpdates:0 reslen:90 0ms
Thu Mar 14 21:01:04 [conn1] opening db: repgain
Thu Mar 14 21:01:04 [conn1] query repgain.editorconfigs query: { $and: [ { customer: "nokia" }, { category: "restaurant" } ] } ntoreturn:0 keyUpdates:0 locks(micros) W:5302 r:176 nreturned:0 reslen:20 0ms
Thu Mar 14 21:01:04 [conn1] Socket recv() errno:104 Connection reset by peer xx.xxx.xxx.183:60848
Thu Mar 14 21:01:04 [conn1] SocketException: remote: xx.xxx.xxx.183:60848 error: 9001 socket exception [1] server [xx.xxx.xxx.183:60848]
Thu Mar 14 21:01:04 [conn1] end connection xx.xxx.xxx.183:60848 (0 connections now open)
junit test script:
public class CopyEditorConfig {
protected final Log logger = LogFactory.getLog(getClass());
private static final String CUSTOMER = "customerx";
private static final String CATEGORY = "categoryx";
@Test
public void test() {
try {
ObjectMapper om = new ObjectMapper();
// script copies the config from m2 to m1.
Mongo m1 = new Mongo("xxx.xxx.com", 29017); // devel
Mongo m2 = new Mongo("yyy.yyy.com", 27017); // live
Assert.assertNotNull(m1);
Assert.assertNotNull(m2);
logger.info("try to connect to db \"dbname\"");
DB db2 = m2.getDB("dbname");
logger.info("get collection \"config\"");
DBCollection c2 = db2.getCollection("config");
JacksonDBCollection<EditorTabConfig, ObjectId> ec2 = JacksonDBCollection.wrap(c2, EditorTabConfig.class, ObjectId.class);
logger.info("find entry with customer {" + CUSTOMER + "} and category {" + CATEGORY + "}");
EditorTabConfig config2 = ec2.findOne(DBQuery.and(DBQuery.is("customer", CUSTOMER), DBQuery.is("category", CATEGORY)));
// config
if (config2 == null) {
logger.info("no customer found to copy.");
} else {
logger.info("Found config with id: {" + config2.objectId + "}");
config2.objectId = null;
logger.info("copy config");
boolean found = false;
DB db1 = m1.getDB("dbname");
DBCollection c1 = db1.getCollection("config");
JacksonDBCollection<EditorTabConfig, ObjectId> ec1 = JacksonDBCollection.wrap(c1, EditorTabConfig.class, ObjectId.class);
EditorTabConfig config1 = ec1.findOne(DBQuery.and(DBQuery.is("customer", CUSTOMER), DBQuery.is("category", CATEGORY)));
if (config1 != null) {
found = true;
}
if (found == false) {
WriteResult<EditorTabConfig, ObjectId> result = ec1.insert(config2);
ObjectId id = result.getSavedId();
logger.info("INSERT config with id: " + id);
} else {
logger.info("UPDATE config with id: " + config1.objectId);
ec1.updateById(config1.objectId, config2);
}
StringWriter sw = new StringWriter();
om.writeValue(sw, config2);
logger.info(sw);
}
} catch (Exception e) {
logger.error("exception occured: ", e);
}
}
}
当我在eclipse中读取日志时,运行此脚本似乎很成功。我得到id
和c1
的{{1}},数据也在此处。日志甚至声明,它没有在devel上找到配置并插入它。如果我把它手动放在那里也是如此。然后它会“更新”。但mongo日志保持不变。
发生套接字异常,并且数据永远不会写入db。
我没有好好的想法来调试这个。如果可以的话,我很乐意从这里获得一些提示。此外,如果缺少任何信息,请告诉我,我很乐意分享。
此致 亚历
答案 0 :(得分:2)
您的mongo服务器似乎存在连接问题。以下方法可以帮助您更好地诊断mongo服务器:
尝试从日志文件中获取更多信息:
$ less /var/log/mongo/mongod.log
或 mongod.conf
尝试使用mongostat监控服务器状态:
$ mongostat -u ADMIN_USER -p ADMIN_PASS
尝试使用mongo cli检查服务器运行状态:
$ mongo admin -u ADMIN_USER -p ADMIN_PASS
$ db.serverStatus()
有时可能会遇到Linux系统配置。尝试调整Linux以获得更多连接和限制,这可能有所帮助。 要检查当前的Linux限制,请运行:
$ ulimit -a
以下建议可能会有所帮助:
Linux将每个连接视为一个打开的文件。默认的最大打开文件数为1024.要增加此限制:
修改 /etc/security/limits.conf :
root soft nofile 500000
root hard nofile 512000
root soft nproc 500000
root hard nproc 512000
修改 /etc/sysctl.conf
fs.file-max=360000
net.ipv4.ip_local_port_range=1024 65000
答案 1 :(得分:2)
注释掉你的mongod.conf中将IP绑定到127.0.0.1的行。 通常,默认设置为127.0.0.1。 对于Linux,此配置文件位置应为/etc/mongod.conf。一旦你评论出来,它将从所有接口接收连接。这对我来说是固定的,因为我也得到了这些套接字异常。