微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

奇怪的Tomcat中断,可能与maxConnections有关

在我们公司,我们今天遇到了一个严重的问题:生产服务器停机。 大多数人通过浏览器访问我们的软件无法获得连接,但是已经使用该软件的用户能够继续使用它。 即使我们的热备份服务器也无法与使用HTTP的生产服务器进行通信,甚至不能连接到更广泛的互联网。 整个过程中,服务器可以通过ping和ssh访问,事实上它的负载非常低,通常在5%的cpu负载下运行,而且在这个时候甚至更低。 我们几乎没有磁盘I / O。

问题开始几天后,我们有一个新的变化:端口443(HTTPS)响应,但端口80停止响应。 服务器负载很低。 重新启动tomcat之后,端口80再次开始响应。

我们使用tomcat7,maxThreads =“200”,并使用maxConnections = 10000。 我们将所有的数据都存储在主存中,因此每个HTTP请求都会很快完成,但我们有大量的用户进行非常简单的交互(这是高中学科select)。 但是,我们似乎不太可能在同一时间在我们的页面上打开浏览器的所有10,000个用户

我的问题有几个部分:

Powerpoint PPT转换为JPG或PNG图像转换使用PHP

在linux中获得一个具有2个特定单词的行的最后一个出现

改变glibc,但没有任何反应

从Windows和Eclipse连接到gitolite服务器

在Linux中监视文件访问

“maxConnections”参数可能是我们的灾难的原因吗?

是否有任何理由不把“maxConnections”设置为一个可笑的高值,例如100,000? (即这样做的成本是多less?)

当tomcat遇到“maxConnections”消息时,是否会在任何地方输出警告消息? (我们没有注意到任何东西)。

有可能有一个操作系统限制,我们正在打? 我们使用的是CentOS 6.4(Linux),“ulimit -f”是“unlimited”。 (防火墙是否理解Tcp / Ip连接的概念?其他地方是否有限制?

当tomcat遇到“maxConnections”限制时会发生什么? 它是否尝试closures一些不活动的连接? 如果没有,为什么不呢? 我不喜欢这样的想法:我们的服务器可以被拥有浏览器的人拿走赎金,发送保持活动状态来保持连接的开放。

但主要问题是,“我们如何修复我们的服务器?”

Stefan和Sharpy要求提供更多信息:

我们的客户直接与这台服务器通信

TCP连接在某些情况下立即被拒绝,在其他情况下超时

即使将我的浏览器连接到networking内的服务器,或与热备用服务器(也在同一networking中)无法执行通常通过HTTP发生的数据库复制消息

IPTables – 是的,IPTables6 – 我不这么认为。 无论如何,当我注意到问题后,我的浏览器和服务器之间什么也没有。

更多信息:当我们意识到我们正在使用BIO的认Tomcat7设置(每个连接有一个线程),并且我们有maxThreads = 200时,看起来确实看起来像解决了问题。 实际上,'netstat -an'显示了大约297个连接,匹配200 +队列100.所以我们将其更改为NIO并重新启动了tomcat。 不幸的是第二天发生了同样的问题。 有可能我们错误地configuration了server.xml。

server.xml和从catalina.out提取在这里: https ://www.dropBox.com/sh/sxgd0fbzyvuldy7/AACZWoBKXNKfXjsSmkgkVgW_a?dl =0

更多信息:我做了一个负载testing。 我能够从我的开发笔记本电脑创build500个连接,并且每次都进行HTTP GET 3次,没有任何问题。 除非我的负载testing无效(java类也在上面的链接中)。

良好的Linux / Ubuntu的OpenGL教程?

在AWS lambda上从nodejs调用python – permission denied

更好的方式来监视和杀死其他程序在Linux中停滞的过程?

Linux上的进程Deluge

在Ubuntu 11.10中访问物理内存

如果没有亲自进行调试,很难确定,但是我要检查的第一件事情是文件描述符限制(这是ulimit -n )。 TCP连接使用文件描述符,并且取决于使用哪个实现,使用SelectableChannel进行轮询的nio连接可能会在每个打开的套接字上使用多个文件描述符。

要检查这是否是原因:

使用ps查找Tomcat PID

检查进程运行的ulimit : cat /proc/<PID>/limits | fgrep 'open files' cat /proc/<PID>/limits | fgrep 'open files'

检查有多少个描述符正在使用中: ls /proc/<PID>/fd | wc -l ls /proc/<PID>/fd | wc -l

如果使用的描述符的数量明显低于限制,那么问题的原因就是其他原因。 但是,如果它是相等或非常接近极限,这是造成问题的这个限制。 在这种情况下,您应该为Tomcat运行的用户增加/etc/security/limits.conf的限制,并从新打开的shell重新启动进程,如果新限制使用了/proc/<PID>/limits实际上是用了,看看Tomcat的行为是否有所改善。

虽然我没有直接的答案来解决您的问题,但我想提供一些方法来找出问题所在。

直觉上有三个假设:

如果您的客户端保持连接而不释放,即使没有通信,您的服务器也有可能达到最大连接限制。

也可以通过各种方式来达到无响应状态,例如服务器端代码中的错误

硬件条件不应忽视。

要找出这个问题的原因,最好在测试环境中重播这个场景。 执行更全面的测试并记录更详细的日志,包括但不限于:

单元测试,尤其是 逻辑块使用事务,线程和同步。

以压力为导向的测试。 尝试模拟所有可以提出的用户行为及其组合,并以大批量模式进行测试。 ( ref )

更多指定日志记录。 跟踪客户端行为并分析服务器停止响应之前发生的事情。

更换服务器机器,看看它是否仍然会发生。

你确定你没有达到maxThreads限制吗? 你试过改变它吗?

现在,浏览器将同时连接限制在每个主机名/ IP最多4个,所以如果你有50个同时浏览器,你可以很容易地达到这个限制。 尽管希望你的webapp能够快速响应来处理这个问题。 长时间的投票最近变得流行(直到websockets更为流行),所以你可能有200多个民意调查。

一个原因可能是,如果您使用HTTP [S]进行应用程序到应用程序的通信(即没有涉及到浏览器)。 有时候,应用程序编写者会马虎,创建新的连接来并行执行多个任务,导致TCP和HTTP开销。 仔细检查,你没有得到一个请求的洪水。 日志文件通常可以帮助您,或者您可以使用wireshark来统计HTTP请求或HTTP [S]连接的数量。 如果可能,请修改您的API以在一个HTTP请求中处理多个API调用

与最后一个相关的是,如果你有很多HTTP / 1.1请求通过一个连接,并且中间代理可能会将它们分成多个连接以达到负载平衡的目的。 听起来很疯狂,我知道,但我已经看到它发生。

最后,一些抓取机器人会忽略robots.txt中设置的抓取延迟。 日志文件和/或wireshark可以帮助您确定这一点。

总的来说,运行更多的实验更多的变化。 maxThreads,https等,然后再跳到maxConnections的结论。

我想你需要使用Apache JMeter来调试应用程序的连接数量,并使用Jconsole或Zabbix为tomcat服务器寻找堆空间或线程转储。

Apache tomcat的Nio连接器最多可以有10000个连接,但是我不认为提供这么多连接到tomcat的一个实例更好的方法是做一个好主意,就是运行多个tomcat实例。

在我看来,生产服务器的最佳途径:在前面运行Apache http服务器,并使用AJP连接器将您的tomcat实例指向该http服务器。

希望这可以帮助。

简短的回答:

使用NIO连接器而不是认的BIO连接器

将“maxConnections”设置为例如10,000

鼓励用户使用HTTPS,以便中间代理服务器不能将100个页面请求转换为100个tcp连接。

检查由于死锁问题而挂起的线程,例如,使用堆栈转储(kill -3)

(如果适用,如果您尚未执行此操作,请编写您的客户端应用程序以使用一个连接进行多个页面请求)。

漫长的回答:

我们使用的是BIO连接器而不是NIO连接器。 两者的区别在于BIO是“每个连接一个线程”,而NIO是“一个线程可以服务多个连接”。 所以,如果我们不增加“maxThreads”,那么增加“maxConnections”是不相关的,因为我们不了解BIO / NIO的差异。

要将其更改为NIO,请将其放在server.xml中的元素中:protocol =“org.apache.coyote.http11.Http11NioProtocol”

从我读到的,使用BIO没有任何好处,所以我不知道为什么它是认的。 我们只使用它,因为它是认的,我们假设认设置是合理的,我们不希望成为tomcat调优的专家,到现在我们已经有了。

但是,即使在做出这个改变之后,我们也发生了类似的情况:同一天,即使在HTTP正在运行时,HTTPS也变得没有响应,然后稍后发生了相反的情况。 这有点令人沮丧。 我们检查了'catalina.out',实际上NIO连接器正在被使用。 所以我们开始了长时间的分析“netstat”和wireshark。 我们注意到连接数量出现了一些高峰 – 在一个案例中,当基线为70时,多达900个连接。当我们在主生产服务器和我们在每个客户处安装的“设备”之间同步数据库时,出现了这些高峰现场(学校)。 我们做的同步越多,造成中断的就越多,这使得我们在下降的螺旋上做了更多的同步。

看起来似乎在发生的事情是,新南威尔士州教育局代理服务器将我们的数据库同步流量分成多个连接,因此1000个页面请求变为1000个连接,而且在TCP 4分钟超时之前它们不能正常关闭。 代理服务器只能这样做,因为我们使用的是HTTP。 他们这样做的原因大概是负载平衡 – 他们认为通过在4台服务器上分割页面请求,他们会得到更好的负载平衡。 当我们切换到HTTPS时,他们无法做到这一点,只能使用一个连接。 所以这个特定的问题就被消除了 – 我们不再看到连接数量的爆发。

人们建议增加“maxThreads”。 事实上,这会改善事情,但这不是“正确”的解决方案 – 我们有200个认的解决方案,但是在任何时候,这些东西几乎没有做任何事情,事实上几乎没有任何这些解决方案被分配给页面请求。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。

相关推荐