有些 Apache 请求很慢,大多数请求可以立即完成

有些 Apache 请求很慢,大多数请求可以立即完成

我有两台 Dell R410 Web 服务器(2 个四核 Xeon E5520,8GB 内存),运行 Debian 5 稳定版。它们的补丁已经被忽视了一段时间,所以最近我们进行了一次补丁运行,以使所有内容保持最新状态 - 这是因为它运行的应用程序的新版本需要 PHP 5.3.6。内核没有更新,因为它来自 Debian backports 存储库(安装的版本是 2.6.30-bpo.1-amd64)。

自补丁发布以来,用户一直抱怨网站速度太慢。大多数请求都能立即得到处理,但偶尔也会在某个请求上“卡住”。卡住的请求似乎没有任何明显的规律。

这些服务器位于负载平衡器后面,它们同时更新,并且在运行修补程序时都开始出现此问题。它们当时没有重新启动,但此后一直没有效果。

我在服务器上设置了一个脚本来循环time curl localhost:80/alive,其中有一个简单的 index.html 文件,只包含“OK”。奇怪的是,这些请求仍然会延迟,延迟频率和持续时间与实际 php 内容的请求相同。常见的时间是 3 秒、9 秒、25 秒、45 秒,有些甚至超过 3 分钟。45 秒是常见的响应时间,但浏览器当然会在此之前放弃,因此实际上没有响应。

Apache 工作进程配置如下:

<IfModule mpm_prefork_module>
    StartServers        50
    MinSpareServers     10
    MaxSpareServers     150
    ServerLimit         500
    MaxClients          500
    MaxRequestsPerChild   5000
</IfModule>

对于拥有 8GB 内存的服务器来说,这似乎是合理的。实际上,工作线程数量很少超过 170,因此我们不会达到该限制,而且有足够的可用内存。平均负载较低,徘徊在 0.5-1.5 左右

内核是一个旧的反向移植,所以我尝试将其更新到 lenny 的最新反向移植(2.6.32-bpo.5-amd64),但它在启动时出现故障,我不得不让我们的主机用旧版本重新启动它,所以在我们尝试更新它们的 bios 并用 Debian 6 格式化它们之前,我想探索其他选项。

Apache 似乎是罪魁祸首,因此下一步是更新到最新的 apache 反向移植,但版本从 2.2.9-10+lenny4 到 2.2.9-10+lenny9 只是一个小变化,所以我没想到会有任何重大变化。

安装了 PHP,版本 5.3.6,来自 dotdeb。以前的版本是 5.3.0 自定义编译。此外,我的老板刚刚告诉我,通过 https 的请求不会延迟,但我自己还没有确认这一点。

# apache2 -V
Server version: Apache/2.2.9 (Debian)
Server built:   Dec 11 2010 21:34:00
Server's Module Magic Number: 20051115:15
Server loaded:  APR 1.2.12, APR-Util 1.2.12
Compiled using: APR 1.2.12, APR-Util 1.2.12
Architecture:   64-bit
Server MPM:     Prefork
  threaded:     no
    forked:     yes (variable process count)
Server compiled with....
 -D APACHE_MPM_DIR="server/mpm/prefork"
 -D APR_HAS_SENDFILE
 -D APR_HAS_MMAP
 -D APR_HAVE_IPV6 (IPv4-mapped addresses enabled)
 -D APR_USE_SYSVSEM_SERIALIZE
 -D APR_USE_PTHREAD_SERIALIZE
 -D SINGLE_LISTEN_UNSERIALIZED_ACCEPT
 -D APR_HAS_OTHER_CHILD
 -D AP_HAVE_RELIABLE_PIPED_LOGS
 -D DYNAMIC_MODULE_LIMIT=128
 -D HTTPD_ROOT=""
 -D SUEXEC_BIN="/usr/lib/apache2/suexec"
 -D DEFAULT_PIDLOG="/var/run/apache2.pid"
 -D DEFAULT_SCOREBOARD="logs/apache_runtime_status"
 -D DEFAULT_LOCKFILE="/var/run/apache2/accept.lock"
 -D DEFAULT_ERRORLOG="logs/error_log"
 -D AP_TYPES_CONFIG_FILE="/etc/apache2/mime.types"
 -D SERVER_CONFIG_FILE="/etc/apache2/apache2.conf"

# apache2ctl -t -D DUMP_MODULES
Loaded Modules:
 core_module (static)
 log_config_module (static)
 logio_module (static)
 mpm_prefork_module (static)
 http_module (static)
 so_module (static)
 alias_module (shared)
 auth_basic_module (shared)
 authn_file_module (shared)
 authz_default_module (shared)
 authz_groupfile_module (shared)
 authz_host_module (shared)
 authz_user_module (shared)
 autoindex_module (shared)
 cgi_module (shared)
 deflate_module (shared)
 dir_module (shared)
 env_module (shared)
 geoip_module (shared)
 mime_module (shared)
 negotiation_module (shared)
 php5_module (shared)
 rewrite_module (shared)
 setenvif_module (shared)
 ssl_module (shared)
 status_module (shared)
Syntax OK

非常感谢您的帮助!

答案1

我已经为此苦苦挣扎了一个星期了,现在我的老板已经解决了。

当我们查看日志中的 Apache 响应时间时,我们发现它响应很快 - 延迟甚至在请求到达 Apache 之前就发生了。因此,他查看了 tcp 堆栈设置,并将其与运行 Red Hat 5.6 的另一台服务器进行比较。

长话短说,启用 tcp syn cookies(net.ipv4.tcp_syncookies=1在 /etc/sysctl.conf 中)已解决问题。此设置旨在防止 SYN 洪水,显然确实允许更快的响应。我们可能意外(或故意)被洪水淹没。

更多信息请参见此链接,所描述的症状正是我们所看到的:http://baheyeldin.com/technology/linux/detecting-and-preventing-syn-flood-attacks-web-servers-running-linux.html

我当时正在看netstat -alnt,发现绝大多数连接都处于 TIME_WAIT 状态,而不是 SYN_RECV(也许 -l 选项没有显示半开连接)。

然而我们现在经常在 dmesg 中看到这种情况:

possible SYN flooding on port 80. Sending cookies.

我应该做更多的挖掘。

相关内容