gpt4 book ai didi

java - Tomcat 与 Azure 中的 MongoDB 通信时出现超时错误

转载 作者:可可西里 更新时间:2023-11-01 09:12:25 25 4
gpt4 key购买 nike

我的系统是在 Ubuntu 上运行的 TomCat 7 服务器,与在 CentOS 中运行的 MongoDB 集群进行通信。我们在 AWS 上有这个,并且运行良好。

我最近在 Azure 上提出了完全相同的问题,当 tomcat 应用程序尝试查询 MongoDB 时,我们遇到了持续的、看似随机的超时。典型的错误是:

Jan 31 08:13:54 catalina.out:  Jan 31, 2014 4:14:09 PM com.mongodb.DBPortPool gotError
Jan 31 08:13:54 catalina.out: WARNING: emptying DBPortPool to xxx.cloudapp.net/xxx.xxx.xxx.xxx:21191 b/c of error
Jan 31 08:13:54 catalina.out: java.net.SocketException: Connection timed out
Jan 31 08:13:54 catalina.out: at java.net.SocketInputStream.socketRead0(Native Method)
Jan 31 08:13:54 catalina.out: at java.net.SocketInputStream.read(SocketInputStream.java:146)
Jan 31 08:13:54 catalina.out: at java.io.BufferedInputStream.fill(BufferedInputStream.java:235)
Jan 31 08:13:54 catalina.out: at java.io.BufferedInputStream.read1(BufferedInputStream.java:275)
Jan 31 08:13:54 catalina.out: at java.io.BufferedInputStream.read(BufferedInputStream.java:334)
Jan 31 08:13:54 catalina.out: at org.bson.io.Bits.readFully(Bits.java:46)
Jan 31 08:13:54 catalina.out: at org.bson.io.Bits.readFully(Bits.java:33)
Jan 31 08:13:54 catalina.out: at org.bson.io.Bits.readFully(Bits.java:28)
Jan 31 08:13:54 catalina.out: at com.mongodb.Response.<init>(Response.java:40)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBPort.go(DBPort.java:142)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBPort.call(DBPort.java:92)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBTCPConnector.innerCall(DBTCPConnector.java:244)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBTCPConnector.call(DBTCPConnector.java:216)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBApiLayer$MyCollection.__find(DBApiLayer.java:288)
Jan 31 08:13:54 catalina.out: at com.mongodb.DB.command(DB.java:262)
Jan 31 08:13:54 catalina.out: at com.mongodb.DB.command(DB.java:244)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBCollection.getCount(DBCollection.java:985)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBCollection.getCount(DBCollection.java:956)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBCollection.getCount(DBCollection.java:931)
Jan 31 08:13:54 catalina.out: at com.mongodb.DBCollection.count(DBCollection.java:878)
Jan 31 08:13:54 catalina.out: at com.eweware.service.base.store.impl.mongo.dao.BaseDAOImpl._exists(BaseDAOImpl.java:788)
Jan 31 08:13:54 catalina.out: at com.eweware.service.base.store.impl.mongo.dao.GroupDAOImpl._exists(GroupDAOImpl.java:18)

我正在使用 Java 驱动程序 2.11.4 并按如下方式初始化它:

        builder.autoConnectRetry(true)
.connectionsPerHost(10)
.writeConcern(WriteConcern.FSYNCED)
.connectTimeout(30000)
.socketKeepAlive(true);

在浏览互联网时,我看到一些 Material 表明存在 Azure 问题和一些 C# 建议,但我还没有看到任何有关如何从 Java 纠正它的内容。

更多细节:

  1. 当 MongoDB 是单个节点或副本集时会发生这种情况
  2. 无论服务器是否处于负载状态,都会发生这种情况。事实上,服务器在某些负载下的性能似乎比冷启动时的性能更好。但即使在恒定负载下它也会超时
  3. 超时似乎是随机的,因为对于什么调用将失败或何时失败没有可辨别的模式。有时一个小时不会出现任何问题,有时每次调用都会失败
  4. 如果我在超时错误时重试调用,最终它会起作用。有时需要重试超过 100 次,有时只需重试一次即可。

这是我正在尝试的重试代码:

private DBObject findOneRetry(DBObject criteria, DBObject fields, DBCollection collection) throws SystemErrorException {
DBObject obj = null;
for (int attempt = 1; attempt < MAX_RETRIES; attempt++) {
try {
obj = collection.findOne(criteria, fields); // getting SocketException inside here
return obj;
} catch (Exception e) {
if (attempt > MAX_RETRIES) {
throw new SystemErrorException(makeErrorMessage("findOneRetry", "find", attempt, e, null), e, ErrorCodes.SERVER_DB_ERROR);
} else {
logger.warning(getClass().getName() + ": findOneRetry failed and will retry in attempt #" + attempt + " in collection " + _getCollection());
}
}
}
return obj;
}

关于如何纠正有什么建议吗?

提前致谢!

最佳答案

这是由于 CentOS 服务器中的 tcp_keepalive_time 太长造成的。

在您的 MongoS 服务器中:sudo nano/proc/sys/net/ipv4/tcp_keepalive_time将 7200 更改为 60

重新启动 Azure 实例。

更新:为了确保您的虚拟机始终具有 tcp_keepalive_time 值:

添加此行:

bash -c 'echo 60 > /proc/sys/net/ipv4/tcp_keepalive_time'

至:

/etc/rc.d/rc.local

更新更新:对于大多数 Linux 版本,都有一个 /etc/sysctl.d/ 目录。创建一个文件,例如mongo.conf 包含:

net.ipv4.tcp_keepalive_time = 60

将文件放入该目录并运行:

sysctl -p /etc/sysctl.d/mongo.conf

验证更改:

sysctl net.ipv4.tcp_keepalive_time

在我遇到过的基于 RedHat 和 Debian 的系统中,这将在重新启动后继续存在。您需要确保并检查 /etc/sysctl.conf 以及 /etc/sysctl.d 中的任何其他文件,以查看该变量是否已设置为其他内容并进行适当的更改。

关于java - Tomcat 与 Azure 中的 MongoDB 通信时出现超时错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21485653/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com