![Apache 没有响应,在短暂而强烈的“流量波”之后没有记录任何内容](https://linux22.com/image/798946/Apache%20%E6%B2%A1%E6%9C%89%E5%93%8D%E5%BA%94%EF%BC%8C%E5%9C%A8%E7%9F%AD%E6%9A%82%E8%80%8C%E5%BC%BA%E7%83%88%E7%9A%84%E2%80%9C%E6%B5%81%E9%87%8F%E6%B3%A2%E2%80%9D%E4%B9%8B%E5%90%8E%E6%B2%A1%E6%9C%89%E8%AE%B0%E5%BD%95%E4%BB%BB%E4%BD%95%E5%86%85%E5%AE%B9.png)
我的 apache 持续处理大约 300 个请求/秒(2 兆字节/秒),服务器负载为 0.05。
问题是,我的服务架构导致特定时刻产生巨大的流量(例如,几秒钟内 300-500 人通过 JavaScript 重定向到某个页面)。
经过如此短暂的流量跳跃后,Apache 变得无响应(在 Firefox 中大约 30 秒后连接重置),没有记录任何内容。Apache 被冻结,直到 apache2 重新启动程序。
当冻结时,如果没有 PHP 或 SQL 连接,它甚至无法提供简单的 HTML 文件(但 apache2 进程存在)
我尝试了不同的预分叉设置,从 50 到几乎 1000 个空闲工作者和最大客户端限制 10000,但没有任何帮助。
除了不记录任何内容之外,另一个症状是,在冻结之前,apache 状态模块显示(上次无响应之前)几乎每个进程都在等待连接:
__R_R_______R__RR______R___R________________RR_______R______R___
_________R__________R_________________________R________CR___R___
___________R__________________________C__WR__R________________R_
但在正常的、负荷较少的工作中,它表现为:
C___R___K_C___C___C_____KK______R___C_C_R______C__K___C________K
____C__KR_RR__C___K___KK_C__R__K__C_CK__RC___CR___R__K__C__R____
___KR____C_____R______R______K__R_______KC__C_K__R____C_______R_
syslog 也没有给出任何信息。我的机器有 64GB RAM,负载从未超过 0.1
答案1
我认为,当您的连接数每秒激增超过 450 个时,这可能与 Linux 中的临时端口耗尽有关。
之前查看过这个回答的问题
答案的小摘要:
sysctl net.ipv4.ip_local_port_range
sysctl net.ipv4.tcp_fin_timeout
临时端口范围定义了主机可以从特定 IP 地址创建的最大出站套接字数。fin_timeout 定义了这些套接字保持 TIME_WAIT 状态(使用一次后不可用)的最短时间。通常的系统默认值为:
net.ipv4.ip_local_port_range = 32768 61000
net.ipv4.tcp_fin_timeout = 60
这基本上意味着您的系统无法保证在任意给定时间有超过 (61000 - 32768) / 60 = 470 个套接字。如果您对此不满意,可以从增加 port_range 开始。如今将范围设置为 15000 61000 非常常见。您可以通过减少 fin_timeout 来进一步提高可用性。假设您同时执行这两个操作,您应该更容易看到超过 1500 个出站连接。
答案2
您能附加到正在运行的无响应进程并查看会发生什么吗?如果运行 prefork,可能会更容易。
使用跟踪附加到进程
strace -p <pid> -o /tmp/somefile
你可能想玩一下 -s
-s strsize Specify the maximum string size to print (the default is 32). Note that filenames are not considered strings and are always printed in full.
答案3
我同意 3molo 的观点,strace 可以提示发生了什么,例如是否有系统调用挂起。我发现 strace 对慢速 io 问题没什么用。运行
sudo iotop
和
sudo top
可以稍微了解一下正在发生哪种类型的 IO 活动。过去,缓慢的 IO 也曾导致过类似的行为;例如,必须从缓慢的 NAS 读取许多非常小的文件。如果 top 报告了较高的“等待”时间,并且 iotop 显示带宽百分比很高,则可能需要应用不同的存储解决方案。
答案4
听起来很像文件描述符限制。您需要su
向运行 apache 的用户发出请求,然后运行以下命令:
ulimit -n
很多发行版的默认设置似乎是 1024。如果是这样,请尝试调高该值。您可以在基于 Debian 的发行版的 /etc/security/limits.conf 中更改它。假设用户 apache 按原样运行apache
,那么您可以添加以下内容:
apache soft nofile 65535
apache hard nofile 65535
您需要重新启动才能应用此更改。