Apache 使用 mod_reqtimeout 进行性能测试时出现的问题

Apache 使用 mod_reqtimeout 进行性能测试时出现的问题

我们在负载均衡器后面有 2 个 Apache 网络服务器,它们通过 mod ajp 连接到 2 个(JBoss)应用程序服务器。

移动设备通过 REST API 连接到这些网络服务器。

在我们的性能测试中,我们很快遇到了很多 NonHttpResponse: 错误,我们发现这些错误来自 mod_reqtimeout:

[Mon Mar 16 14:42:49.324705 2015] [reqtimeout:info] [pid 27914:tid 140628428449536] [client 1.2.3.4:48280] AH01382: Request header read timeout

...其配置如下:

<IfModule reqtimeout_module>
    RequestReadTimeout header=10-20,minrate=500
    RequestReadTimeout body=10,minrate=500
</IfModule>

我可以通过将那些值增加到

RequestReadTimeout header=20-60,minrate=100

但这不能解决问题,因为随着更多同时用户,问题再次出现(要求能够为 300 个并发用户提供服务 - 100 个工作正常,而 300 个用户时,我们遇到了超过 10,000 个请求标头读取超时错误)。我怀疑是 apaches KeepAlive、我们的 mod_ajp 配置和 mod_reqtimeout 之间的相互作用导致 mod_reqtimeout 得出存在 slowloris 攻击的结论(许多打开的连接什么也不做),我恳请您帮助调整这些参数。

另一个问题是 Web 服务器和应用程序服务器之间的防火墙,我怀疑它会杀死开放的空闲连接。我读到过完全停用 KeepAlive 来解决这个问题,但正如我所说,我们所有的客户端都是移动设备,所以这可能不是一个选择 (?)。

以下是其他配置(部分):

工人.属性:

worker.list=server
worker.maintain=60

worker.server.type=ajp13
worker.server.host=server
worker.server.port=15869
worker.server.socket_keepalive=True
worker.server.connection_pool_timeout=600
worker.server.ping_mode=A
worker.server.connection_ping_interval=60

mod_prefork:

<IfModule prefork.c>
    StartServers         5
    MinSpareServers      5
    MaxSpareServers     10
    #MaxClients         256
    MaxClients         300
    MaxRequestsPerChild  0
</IfModule>

主服务器.conf:

Timeout 300
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

ssl.conf(移动设备通过 ssl 连接):

Timeout 1200
KeepAlive On
MaxKeepAliveRequests 0
KeepAliveTimeout 10

答案1

在看似本质上是反向代理的环境中,使用“prefork”MPM 是不寻常的,混合“worker”MPM 具有更好的可扩展性,但这不是问题所在。

通常,DoS 缓解措施最好(如果不是由您的 ISP 处理)在前端终止客户端请求的设备,根据您的描述,这是一个负载均衡器,而不是 Apache。任何有能力的负载均衡器都将支持 HTTP(即“第 7 层”),这可能会导致 HTTP 请求缓冲。如果负载均衡器正在终止 HTTPS,这也适用,但如果负载均衡器只是中继 HTTPS 连接(因为它无法看到 HTTP 请求以对其进行缓冲),则情况就不那么适用了。如果您的负载均衡器是一个简单的“第 3/4 层”NAT 类型负载均衡器,它也不适用。

至于超时的可能原因:

  • 如果您的 SSL 实例KeepAliveTimeout与标头读取超时相同RequestReadTimeout,则可能存在竞争,在传入客户端请求/标头的过程中达到保持活动超时。如果我尝试重现此问题,除了 AH01382 错误外,我还会收到 AH01991(SSL 输入过滤器读取失败)和 AH00567(请求失败:读取标头时出错)。但这可能无法解释所有问题。
  • 客户端请求格式错误,过去很常见(例如 POST 后出现额外的 CR/LF,错误后重试时请求不完整)。不过我不知道目前有什么问题,这取决于您的客户群,更重要的是他们的连接性。
  • 可能存在类似这样的错误最近的一个这导致“事件” MPM 出现虚假超时。

重现超时:

 $ openssl s_client -connect myhost:443
 GET / HTTP/1.1
 Host: myhost.whatever.com 

 [server reply goes here]
 GET / HTTP/1.1
 Host:

您可以编写脚本以使其更容易,否则您必须在配置的 10 秒内输入/粘贴第一个请求和标头,然后输入但不完整在接下来的 10 秒内,您必须为第二个请求提交至少一行完整的内容(请求),然后等待。

减少 KeepAliveTimeout(默认值为 5 秒)可能会有所帮助。请注意,KeepAliveTimeout 是接收完整请求的时间。我认为下一步可能是mod_log_forensic

关于通过 AJP 连接到后端,您是否在阿帕奇Balancer配置?如果我对您的系统理解正确,您给出的 Tomcat 配置不适用于从 Apache httpd 到 Tomcat 的连接。请参阅这里的选项

                          /-> apache httpd + ajp -\            /-> tomcat/jboss
client -> load-balancer  <                         > firewall <
                          \-> apache httpd + ajp -/            \-> tomcat/jboss

相关内容