0

我正在 Eclipse 中开发一个 Java 项目。我有一个登台服务器和一个实时服务器。这两个也有自己的 mongodb,它们在不同的服务器上运行在两个不同的端口(29017 和 27017)上。通过一个 Junit 测试,我想将数据从 live mongo 复制到 devel mongo。

最奇怪的事情:有时它有效,有时我得到一个套接字错误。我想知道为什么 mongo 有时完全拒绝编写插入内容,而在其他日子里它却完美无缺。这是 mongo 日志文件(插入代码的文件)和 Junit 测试脚本的摘录:

蒙哥日志:

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 测试脚本:

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两者c1c2数据也在这里。日志甚至指出,它没有在 devel 上找到配置并将其插入。如果我手动将其放在那里,那也是正确的。然后它得到“更新”。但是 mongo 日志保持不变。发生套接字异常,数据永远不会写入数据库。

我没有好主意来调试这个。如果可以的话,我很乐意从这里获得一些提示。另外,如果缺少任何信息,请告诉我,我很乐意分享。

问候,亚历克斯

4

2 回答 2

2

看来您与 mongo 服务器有连接问题。以下方法可以帮助您更好地诊断 mongo 服务器:

  1. 尝试从日志文件中获取更多信息:

    $less /var/log/mongo/mongod.log

    或在mongod.conf中定义的自定义日志文件

  2. 尝试使用 mongostat 监控服务器状态:

    $ mongostat -u ADMIN_USER -p ADMIN_PASS

  3. 尝试使用 mongo cli 检查服务器运行状态:

    $ mongo admin -u ADMIN_USER -p ADMIN_PASS
    $ db.serverStatus()
    

    更有用的命令位于:http ://docs.mongodb.org/manual/reference/method/

有时它可能会遇到 Linux 系统配置。尝试调整 Linux 以获得更多连接和限制,这可能会有所帮助。要检查当前的 Linux 限制,请运行:

$ ulimit -a

以下建议可能会有所帮助:

Linux 将每个连接视为一个打开的文件。默认打开文件的最大数量为 1024。要增加此限制:

  1. 修改/etc/security/limits.conf

    root    soft    nofile     500000
    root    hard    nofile     512000
    root    soft    nproc      500000
    root    hard    nproc      512000
    
  2. 修改 /etc/sysctl.conf

    fs.file-max=360000
    net.ipv4.ip_local_port_range=1024 65000
    
于 2013-08-01T03:24:57.033 回答
2

注释掉 mongod.conf 中将 IP 绑定到 127.0.0.1 的行。通常,默认设置为 127.0.0.1。对于 Linux,此配置文件位置应为 /etc/mongod.conf。一旦您将其注释掉,它将接收来自所有接口的连接。这为我修复了它,因为我也收到了这些套接字异常。

于 2015-09-24T13:21:54.890 回答