Apache Tomcat http 死机,停止接受请求

Apache Tomcat http 死机,停止接受请求

过去一周,我一直在应对一次激进的机器人爬虫/攻击。该机器人使用随机 IP 和代理字符串进行分发,因此很难阻止,但我有另一个线程来解决这个问题。这个问题是,大量的 http 请求可能会导致 Tomcat 死机。

Tomcat 进程仍然正常,并且没有内存不足,它只是停止接受 http 或 https 请求。它会使任何 http 请求超时,但仍会接受 https 请求(如果 http 受到攻击,有时 https 也会停止)。

我之前看到过“打开文件过多”的错误,所以我将文件限制从 10000 改为 50000,这似乎有帮助,至少 https 崩溃了,但 http 仍然崩溃。我最近没有看到“打开文件过多”的错误。

似乎打开的文件数量过多,为什么 Tomcat 会打开这么多文件,在高负载下会发生文件泄漏吗?服务器有时 6 个月内都正常(因此在正常情况下不会发生泄漏),但之前在高负载下死机过。

该网站规模较大,拥有超过 100 万个页面(动态内容),每日点击量超过 100 万次。

当 Tomcat 收到大量 http 请求(例如长时间每秒 >100 个)时会发生什么?我假设请求将开始备份,如果使用线程池,将没有剩余的线程,它会继续池化请求直到出现故障,还是会开始拒绝请求?

有没有办法在备份一定量后开始拒绝请求?这似乎是防止极端负载下死机或崩溃的唯一方法。

我的 http 和 https 配置不同,所以这可能与 http 死亡的原因有关。https 使用 maxThreads 而 http 没有使用,(默认有多少个线程?)

<Connector port="80" protocol="HTTP/1.1"
               connectionTimeout="20000"
               redirectPort="443"
               URIEncoding="UTF-8" />

<Connector port="443" protocol="org.apache.coyote.http11.Http11NioProtocol"
               maxThreads="150" SSLEnabled="true" scheme="https" secure="true"
               clientAuth="false" sslProtocol="TLS"
               keystoreFile="..." keystorePass="..."
               URIEncoding="UTF-8"/>

使用 Tomcat v8.5.47、CentOS 7.6、Oracle Java 1.8

答案1

这两个连接器都将使用 NIO 实现。

对于 8.5.47,maxConnections 的默认值为 10000,backlog 为 100。

实际情况是,前 10000 个连接将被接受,并依次分配给线程池中的线程(默认 200 个线程)进行处理。处理这些连接需要多长时间取决于应用程序。

如果当前有 10000 个连接,则接下来的 100 个请求将被保留在积压队列中。虽然 Java 尝试将其配置为 100,但操作系统可能会选择忽略该设置。

一旦积压已满,后续连接将被丢弃。

当您看到 HTTP 没有响应时,您可以(希望)通过间隔约 5 秒进行三次线程转储来找出 HTTP 无响应的原因。

相关内容