我发现我们的 Web 服务器上有一个奇怪的问题,Apache 进程似乎停留在 1 或 2 个线程的状态。这让我很不安,因为我原本只是想施加更严格的 ServerLimit,以便可以更安全地提高 php memory_limit。
有人知道解决这个问题的好方法吗?弄清楚这些进程到底在做什么?它们处于什么状态?
我并不完全确定,但我认为这是由于我们从不重新启动 Apache 服务,并且由于各种原因每天执行 2-3 次重新加载造成的。
举个例子,其中一个 Web 服务器闲置着,而另一个 Web 服务器却负担很重:
PID PPID RES THREADS
*15608 1 29 MB 1
8880 1 2 MB 3
14989 1 0 MB 1
25029 1 0 MB 1
2115 15608 3 MB 2
13058 15608 361 MB 2
14556 15608 157 MB 27
19962 15608 23 MB 1
21219 15608 387 MB 3
21600 15608 3 MB 3
21828 15608 3 MB 2
30152 15608 3 MB 2
在这个例子中,我假设有 3 个进程曾经是控制进程(重新加载前),它们不知出于什么原因仍在运行。在附加到新控制进程的进程中,许多进程仍然处于运行状态,每个进程都有 2-3 个线程。
从 11 小时后开始,许多相同的 PID 仍然在 1 个线程中。您可能会想,如果已达到 MaxRequests,该死的东西就会停止运行。
memory usage report for apache2
pid count : 11
thread count : 46
shared mem usage : 670 MB
total resident size : 691 MB
total cpu usage : 79 %
total memory usage : 7 %
average mem / pid : 62 MB
process breakdown
PID PPID RES THREADS
*15608 1 29 MB 1
8880 1 2 MB 3
14989 1 0 MB 1
25029 1 0 MB 1
2115 15608 3 MB 2
19962 15608 23 MB 1
21219 15608 387 MB 3
21600 15608 3 MB 3
21828 15608 3 MB 2
29239 15608 238 MB 27
30152 15608 3 MB 2
process tree
|-apache2-+-3*[apache2---{apache2}]
| |-apache2
| |-2*[apache2---2*[{apache2}]]
| `-apache2---26*[{apache2}]
|-apache2---2*[{apache2}]
|-2*[apache2]
答案1
首先要检查的是这些是否产生了任何额外的进程(你有可用的 pstree 吗?)。php exec 函数是否已启用?
还要检查是否启用了 keepalive 以及 maxRequests 是否设置为合理的值。线程是空闲的还是正在处理内容?
PHP 是否与数据库后端通信?一旦执行线程进入 DB 客户端库,PHP 内存使用和时间限制方面的约束将不再适用,直到线程返回 PHP。您是否看到数据库查询速度缓慢?
其他值得检查的事情是 MTA 是否配置正确 - 例如,如果您使用带有智能中继的 sendmail,并且您配置的地址错误,则 php 的 mail() 函数可能会长时间阻塞。
Rob Olmos 对 Rasmus Lerdorf 的评论作出了回复6年前虽然该说法可能仍有一些道理,但它不太可能适用于主流扩展。
你没有说你使用的是什么操作系统——在我看来,与预分叉相比,Linux 上的线程优势几乎不可察觉。
当然如果你已经用尽其他途径并且没有令人信服的理由坚持使用线程 apache,那么值得尝试预分叉 - 但请先看看其他地方。
答案2
PHP 是否通过 mod_php 运行?PHP 安装文档提供了以下内容:
警告我们不建议在 Apache 2 的生产中使用线程 MPM。请使用 prefork MPM,这是 Apache 2.0 和 2.2 的默认 MPM。有关原因的信息,请阅读有关使用的相关常见问题解答条目具有线程 MPM 的 Apache2
http://www.php.net/manual/en/install.unix.apache2.php
所以我怀疑问题就在这里。