0

我们遇到了一个问题,即 Apache (2.4.10) FCGID (2.3.9) PHP 进程在 Debian 上陷入“工作”状态。

这些 PHP 进程不占用系统资源(除了处理先前请求时使用的内存占用量)并且处于空闲状态。它们仍然附加到正确的逻辑父进程(处理此 vhost 上的请求的 apache2 进程)

将 strace 连接到它们表明它们处于状态:accept(0,我们假设正在侦听接收下一个请求。

在我们的 PHP 处理中添加的应用程序日志记录在 handle_shutdown 函数中显示所有这些请求都已命中 handle_shutdown 函数(没有错误) - 正如您对任何 PHP 处理的请求所期望的那样(因为您总是点击 handle_shutdown 函数),所以最好据我们所知,整个请求已“成功” Apache 访问日志中记录了 200 响应。

但是,apachectl fullstatus fcgid 部分显示该进程是“工作”而不是“就绪”

更改 Fcgid 设置上的回收因子(最大请求数、生命周期、设置的超时时间更高或更低等)似乎不会影响这些发生的规律性。

一个 apachectl graceful 成功地清理了所有空闲的“工作”线程并恢复正常。

但是,当然,如果我们不看就离开,最终,每个进程迟早都会处于这种状态,直到我们最终得到一个完全空闲的服务器,其中我们所有的最大进程(100)都卡在“等待"但闲着。此时内存使用是合理的,当然 CPU、网络等下降到可以忽略不计,因为服务器将响应的唯一请求是 fullstatus(因为它没有命中 PHP vhost 部分)

4

1 回答 1

0

出色地。

事实证明,第一个建议的响应(将 apache2 Mutex 模式设置为来自文件的“sem”:”是正确的,但是当它第一次应用时 - 我们的 apache2 服务不是冷启动而是重新启动,所以当然新的 Mutex 模式不是实际使用。

因此,当测试仍然显示错误时,此建议被注销。


发生了什么?

apache2 fcgid PM 进程保留所有当前子进程的三个列表:“Ready”、“Working”和“Error/Exiting”。

它使用互斥锁(一个锁)来保护这些列表,每当它向它发出处理请求时将子进程的信息块从“就绪”移动到“等待” - 并且当子进程完成请求时再次按顺序将其移回“就绪”。

此互斥锁保护从多个线程或进程访问的共享资源不会被一个进程“覆盖”,而另一个进程也在尝试读取或写入值(导致该其他进程读取不一致的值,或使其写入丢失)通过一次只允许一个进程访问该重要资源。

Debian 上的默认“文件:”互斥锁似乎不能胜任这项工作,偶尔会导致(正如网络上其他地方所建议的那样),同时发生两个状态更改请求,因此一个更改成功,而另一个更改成功(并发) 更改“丢失”。

因此,孩子知道它已经完成,但父母认为它还没有完成。

呸!


道德:在 Debian 上,如果将 apache2 与 fcgid 一起使用,请更改您的互斥锁模式 - 并确保您在 apache 启动之后执行完整的 apache 停止,并且不要相信您的服务器管理员只完成了 apache 重新启动!

于 2017-09-21T09:54:15.183 回答