Apache 偶尔无响应/停滞

Apache 偶尔无响应/停滞

我在 Debian GNU/Linux 8 (jessie) 上运行 Apache http server 2.4、PHP 7.0 和 MySQL 5.5。有时,Apache 会在几秒钟内完全没有响应 - 大约 30 秒或更长时间。在此期间,请求似乎排队 - 当 Apache 最终再次开始正常工作时,大量堆积的请求必须立即处理,这当然也不是那么好。

Apache 无响应的原因尚不清楚,因为:

  • CPU 负载完全下降;Apache、MySQL 或其他任何东西都不会显著使用 CPU
  • Apache error_log 中没有错误
  • MySQL 中没有阻塞查询 - 当我输入“SHOW PROCESSLIST”时没有显示任何内容
  • 每秒一次,access_log 中会出现“内部虚拟连接”
  • 服务器的总体负载不能太高,否则会发生这种情况;即使负载低于平均水平,并且没有太多用户登录我们的系统,也可能发生这种情况
  • 即使只包含以下内容的 PHP 脚本也echo "Hello World!";不会执行
  • 在 PHP 中,不会抛出任何 MySQL 错误,我可以轻松地从 MySQL 控制台执行 MySQL 语句
  • RAM 似乎没问题 - 交换分区使用不多。这是top在停顿期间显示的内容:

    KiB Mem:   6129344 total,  5975748 used,   153596 free,       24 buffers
    KiB Swap:  1952764 total,   199428 used,  1753336 free.  4397256 cached Mem
    

我尝试使用 strace 分析该问题 - 准确地说,当我注意到服务器没有响应时,我在 shell 中输入:

ps auxw | grep apache | awk '{print" -p " $2}' | xargs sudo strace

我观察到,在这段时间内,类似下面的行经常出现在 strace 输出中,而当没有出现问题时,则不会出现:

[pid 13521] fcntl(57, F_SETLK, {type=F_RDLCK, whence=SEEK_SET, start=1073741824, len=1}) = -1 EAGAIN (Resource temporarily unavailable)

正常情况下,当没有问题时,我可以看到如下行:

[pid  3414] fcntl(55, F_SETLK, {type=F_RDLCK, whence=SEEK_SET, start=1073741824, len=1}) = 0

有人知道这意味着什么吗?在我看来,存在某种锁定冲突...

为了完整起见,下面是我的 Apache 配置:

 LogFormat "%h PID %P %l %u %t \"%r\" %s %b \"%{Referer}i\" \"%{User-agent}i\" %V" common
ServerTokens ProductOnly
ServerSignature Off
TraceEnable off

<IfModule mod_ssl.c>
    SSLHonorCipherOrder On
    SSLProtocol ALL -SSLv2 -SSLv3
    SSLCipherSuite EECDH+AES:AES256-SHA:AES128-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH:!EXP:!SRP:!DSS:!LOW;
    SSLVerifyClient none
    SSLVerifyDepth 1
    SSLInsecureRenegotiation Off
</IfModule>

ScriptAlias /cgi-bin52/ /usr/share/phpcgi/php52/
ScriptAlias /cgi-bin53/ /usr/share/phpcgi/php53/
ScriptAlias /cgi-bin54/ /usr/share/phpcgi/php54/
ScriptAlias /cgi-bin55/ /usr/share/phpcgi/php55/
ScriptAlias /cgi-bin56/ /usr/share/phpcgi/php56/
ScriptAlias /cgi-bin70/ /usr/share/phpcgi/php70/

Mutex flock

LoadModule deflate_module /usr/lib/apache2/modules/mod_deflate.so
LoadModule status_module /usr/lib/apache2/modules/mod_status.so

AcceptFilter http none
AcceptFilter https none

ExtendedStatus on
TimeOut 60
KeepAlive Off
MaxKeepAliveRequests 50
KeepAliveTimeout 2
Options Indexes MultiViews FollowSymLinks
MaxRequestWorkers 256
MaxRequestsPerChild 300

您会看到,已经有一个与锁定行为相关的条目:Mutex flock...正如我的 Webhoster 所说,出于稳定性原因,它已由他预先配置。此外,在https://httpd.apache.org/docs/2.4/mod/core.html#mutex,这似乎是少数没有任何问题的选项之一。

我添加了AcceptFilter条目并尝试寻找解决方案,但没有成功。

有人能解释一下我使用 strace 记录的行包含什么fcntl ...含义,或者建议另一种分析问题的方法吗?

答案1

您可以查看strace哪个文件号被阻塞。执行此操作时,ls -l /proc/$pid/fd您将看到该进程的所有打开文件。带有文件号的符号链接将指向相关文件。

我见过这样的问题,通常是会话文件存在此问题。如果是会话文件,请让您的开发人员了解session_write_close()PHP 中的作用以及省略它session_write_close()会对您的负载下的性能造成什么影响。

答案2

fcntl 是内核尝试设置文件描述符。您没有关注的一件事是磁盘输入/输出等待时间,因此在遇到问题时运行 iostat 或 mpstat 以查看是否存在任何磁盘性能问题。

相关内容