许多长时间运行的 Apache 进程处于 READ 状态,一段时间后没有请求

Posted

技术标签:

【中文标题】许多长时间运行的 Apache 进程处于 READ 状态,一段时间后没有请求【英文标题】:To many long running Apache processes in READ status without requests after a certain time 【发布时间】:2017-05-27 05:26:15 【问题描述】:

我正在使用 /server-status 来监控 Apache 进程。开始时它们看起来像这样:

_____W_K__K____________C_K________C_____________W_..............
................................................................
................................................................

但是经过几个小时的运行看起来是这样的:

R_KCR___KR__RKRR_RRRKRRRRRRKRR_RRCK____R_RRRR_RRRKRRRKRRRRRRRRR_
R_RRRR_R.RR.R_R.R_R..CKRRRRW.K_RCRKRR_R_.._R._.RK_KRK_.RRR.KK_.R
..RR............................................................

有太多的“读取”(R)状态需要很长时间,我不知道他们在做什么,因为他们甚至没有请求。 (提到我从上面的示例中跳过了额外的“。”状态,我总共有 2000 个可用位置。)在进程列表中,我有大约 40 个像这样的“R”进程:

Srv  PID   Acc        M CPU  SS   Req Conn Child Slot   Client       VHost Request
15-2 21291 0/37/11158 R 0.03 7468 2   0.0  1.93  198.35 82.78.95.105

报告的标题如下所示:

Server Version: Apache/2.4.10 (Debian) mod_fcgid/2.3.9 OpenSSL/1.0.1t
Server MPM: prefork
Server Built: Sep 15 2016 20:44:43
Current Time: Thursday, 12-Jan-2017 08:38:46 EET
Restart Time: Wednesday, 11-Jan-2017 00:51:18 EET
Parent Server Config. Generation: 3
Parent Server MPM Generation: 2
Server uptime: 1 day 7 hours 47 minutes 27 seconds
Server load: 0.34 0.35 0.39
Total accesses: 1599556 - Total Traffic: 29.9 GB
CPU Usage: u18.87 s6.81 cu0 cs0 - .0224% CPU load
14 requests/sec - 274.0 kB/second - 19.6 kB/request
90 requests currently being processed, 27 idle workers

我有一个私人服务器:4X3.6GHZ Xeon 处理器、2X512 GB SSD、32 GB 内存、Debian 3.16.36-1、Apache 2.4.10、php 5.6.29、mod_fcgid、php-fpm、php5-cgi , prefork。

我的一些 apache2.conf 设置:

Timeout 14400
KeepAlive On
MaxKeepAliveRequests 1000
KeepAliveTimeout 3
HostnameLookups Off

我的 mpm_prefork.conf 设置:

<IfModule mpm_prefork_module>
  StartServers 50
  MinSpareServers 25
  MaxSpareServers 50
  ServerLimit 2000
  MaxRequestWorkers 2000
  MaxConnectionsPerChild 1000
</IfModule>

我的一些 fcgid.conf 设置:

FcgidMaxRequestLen 1073741824
FcgidOutputBufferSize 1073741824
FcgidMaxProcesses 200
FcgidMaxProcessesPerClass 100
FcgidMinProcessesPerClass 0
FcgidProcessLifeTime 30
FcgidConnectTimeout 30
FcgidIOTimeout 14400
FcgidBusyTimeout 14400
FcgidIdleTimeout 3
FcgidIdleScanInterval 1

我在服务器中有一些长期运行的 cronjobs,这就是为什么我需要 Apache 和 PHP 进程的“14400”(=4 小时)大超时。

问题:

    为什么有这么多没有请求的“R”状态? 他们做了什么,我怎样才能知道? 他们为什么跑这么久?

更新 1:

A 已将超时时间修改为 7200(=2 小时),这是我可以运行我的 cronjobs 的最小值。但是我的 cronjobs 没有问题。

FcgidIOTimeout 7200
FcgidBusyTimeout 7200

也适用于 Apache:

Timeout 7200

基于PHP and mod_fcgid: ap_pass_brigade failed in handle_request_ipc function 我这样做了:

FcgidOutputBufferSize 0

基于mod_fcgid: ap_pass_brigade failed in handle_request function 我这样做了:

FcgidMaxRequestsPerProcess 500

几个小时后服务器停止响应:

服务不可用:服务器暂时无法为您提供服务 由于维护停机时间或容量问题而请求。请尝试 稍后再来。

在日志中我发现了如下两个错误:

[fcgid:warn] (104)Connection reset by peer: mod_fcgid: ap_pass_brigade failed in handle_request_ipc function
[fcgid:warn] (32)Broken pipe: mod_fcgid: ap_pass_brigade failed in handle_request_ipc function

还有一堆这样的(可能针对每个请求):

[fcgid:warn] mod_fcgid: too much processes, please increase FCGID_MAX_APPLICATION

问题 2:

    这些错误是什么意思?我该如何纠正它们? 为什么服务器停止响应?可能是因为错误... mod_fcgid、php-fpm、php5-cgi、prefork 模块是否完全兼容且有效?这是我拿到新服务器时的默认配置。

【问题讨论】:

这里的关键是您的评论“我在服务器中有一些长期运行的 cronjobs,这就是为什么我需要 Apache 和 PHP 进程的“14400”(=4 小时)大超时。阻止他们,问题仍然存在?像 lsof 这样的命令会显示这些孩子的活动连接。另一方面,如果您有 mod_fcgid,则不需要 prefork,并且可以切换到类似线程的 mpm 事件,这样可以更好地扩展。打开的插槽反映了您的备用服务器指令。 OPTIONS 请求来自您的某些东西,apache 不会 ping 自己。 在任何情况下,尝试将超时减少到正常值,您将看到此行为停止。 您的 php 脚本永远挂在那里,因为由于某种原因 mod_fcgid 无法生成更多进程,因为我读到的“FCGID_MAX_APPLICATION”是一个内部表,可以在源代码上更改并重新编译。您使用的是哪个版本的 mod_fcgid?如果不是最后一个,也许你应该升级。我的推荐?迁移到 mod_proxy_fcgi -> php-fpm,这将使您拥有带有 mpm_event 的 apache,而 php-fpm 非常通用,并允许您进行非常不同的隔离设置。 mod_fcgid 版本:1:2.3.9-1+b1 cron 作业的长度与 Apache 中的 TImeout 有何关系? 【参考方案1】:

问题已解决。

解决方案是将 Apache 的 Timeout 值降低到 15 之类的数字。当我意识到运行较长的 PHP 脚本(即使是几个小时)不需要将这个超时设置为高时,PHP 的 @ 就足够了987654323@够大了。

更新

我还在 PHP-FPM 下使用 FastCGI 升级到 PHP 7.1,并且我已将 Apache 的 MPM 模式更改为 esra-s 建议的事件,它运行得像地狱一样。非常感谢!

【讨论】:

你能详细说明一下吗?你是说 PHP 7.1 现在可以在 Apache event mpm 下运行,并且是线程安全的?

以上是关于许多长时间运行的 Apache 进程处于 READ 状态,一段时间后没有请求的主要内容,如果未能解决你的问题,请参考以下文章

分析非常长时间运行的任务

在qthread中停止长时间运行的进程

python multiprocessing.Pool kill *特定*长时间运行或挂起的进程

以与长时间运行的 Python 进程不同的用户身份运行子进程

长时间运行的Django进程可行吗?

如果 Android 设备长时间处于空闲状态,则不会收到推送通知