PHP 和 mod_fcgid:ap_pass_brigade 在 handle_request_ipc 函数中失败
Posted
技术标签:
【中文标题】PHP 和 mod_fcgid:ap_pass_brigade 在 handle_request_ipc 函数中失败【英文标题】:PHP and mod_fcgid: ap_pass_brigade failed in handle_request_ipc function 【发布时间】:2016-02-22 01:07:57 【问题描述】:在https://***.com/a/12686252/219116 之前已经提出并回答了这个问题,但是那里的解决方案对我不起作用。
mod_fcgid 配置
<IfModule mod_fcgid.c>
AddHandler fcgid-script .fcgi
FcgidIPCDir /var/run/mod_fcgid/
FcgidProcessTableFile /var/run/mod_fcgid/fcgid_shm
FcgidIdleTimeout 60
FcgidProcessLifeTime 120
FcgidMaxRequestsPerProcess 500
FcgidMaxProcesses 150
FcgidMaxProcessesPerClass 144
FcgidMinProcessesPerClass 0
FcgidConnectTimeout 30
FcgidIOTimeout 600
FcgidIdleScanInterval 10
FcgidMaxRequestLen 269484032
</IfModule>
php-cgi 脚本
#!/bin/bassh
export PHPRC=/var/www/vhosts/example.com/etc/
export PHP_FCGI_MAX_REQUESTS=5000
exec /usr/bin/php-cgi
系统详情
CentOS Linux 版本 7.1.1503(核心) httpd-2.4.6-31.el7.centos.x86_64 mod_fcgid-2.3.9-4.el7.x86_64 php56u-cli-5.6.12-1.ius.centos7.x86_64所以我的 FcgidMaxRequestsPerProcess 设置为 500,我的 PHP_FCGI_MAX_REQUESTS 设置为 10 倍,如前面的答案和 Apache 文档中所建议的那样。然而我仍然得到这些错误
[Thu Nov 19 18:16:48.197238 2015] [fcgid:warn] [pid 6468:tid 139726677858048]
(32)Broken pipe: [client X.X.X.X:41098] mod_fcgid: ap_pass_brigade failed in handle_request_ipc function
【问题讨论】:
您可能希望从@Vineet1982 的答案中删除已解决的检查。真正的原因可以在 Avian 的博客上阅读:tablix.org/~avian/blog/archives/2016/05/… 【参考方案1】:大约一年前我也遇到了同样的问题,然后我尝试了很多事情,最后我在阅读文档后做了一些即时运行的事情,我的问题就消失了。首先需要设置的重要事项为:
FcgidBusyTimeout 300 [default]
FcgidBusyScanInterval 120 [default]
该指令的目的是终止挂起的应用程序。对于可能需要更长时间来处理请求的应用程序,可能需要增加默认超时。因为检查是在FcgidBusyScanInterval
定义的时间间隔内执行的,所以请求处理可能会被允许进行更长的时间
FcgidProcessLifeTime 3600 [default]
如果该类的进程数超过FcgidMinProcessesPerClass
,则会终止已存在超过此时间的空闲应用程序进程。
此进程生命周期检查以配置的FcgidIdleScanInterval
的频率执行。
FcgidZombieScanInterval 3 [seconds default]
模块在此时间间隔检查退出的 FastCGI 应用程序。在这段时间内,应用程序可能作为僵尸存在于进程表中(在 Unix 上)。
注意:以上所有选项根据您的申请处理时间或需要减少或增加或适用于特定的虚拟主机。
但我的问题可以通过这个选项解决:
上面的选项已经调整了我的服务器,但过了一段时间,错误似乎又出现了,但错误确实可以通过以下方式解决:
FcgidOutputBufferSize 65536 [default]
我已经改成
FcgidOutputBufferSize 0
这是模块在将数据刷新到客户端之前将从 FastCGI 应用程序读取的最大响应数据量。这将立即刷新数据,而不是等待 64KB 字节,这确实有助于我更快地刷新进程。
我遇到的其他问题
如果 500 错误来自 nginx 超时。修复:
/etc/nginx/nginx.conf
keepalive_timeout 125;
proxy_read_timeout 125;
proxy_connect_timeout 125;
fastcgi_read_timeout 125;
我会间歇性地收到 mysql“MySQL 服务器已消失”错误,这需要再进行一次调整: /etc/my.conf
wait_timeout = 120
然后,为了好玩,我继续提高了我的 PHP 内存限制,以防万一: /etc/php.ini
memory_limit = 256M
使用 SuExec
mod_fastcgi
在SuExec
和Apache 2.x
下根本不起作用。我只遇到了麻烦(它在我们的测试中还有许多其他问题)。问题的真正原因是 SuExec
就我而言,这对我来说是一个初创公司,我启动了 Apache,mod_fcgid 为每个虚拟主机生成了 5 个进程。现在,当使用一个简单的上传脚本并提交一个大于 4-8KB 的文件时,所有这些子进程都会为执行该脚本的特定 vhost 立即终止。
也许可以在 mod_fcgid 中进行调试构建或加速登录,这可能会提供线索。
在此期间我尝试了 mod_fastcgi 1 年,我也可以和其他许多人说,SuExec 在任何情况下都只是麻烦且运行不顺畅。
【讨论】:
不幸的是,将 FcgidOutputBufferSize 设置为 0 并不能消除 ap_pass_brigade 错误。我们甚至知道这个错误意味着什么吗? 针对不同的传入请求分发到特定的 CGI 服务器、负载平衡、多个网站托管等... @Slashterix 请让我知道 PHP 的模式,因为它必须使用 php-fpm 运行,如果没有,请切换到它,您的问题就会消失。如果没有,请再次告诉我 我没有使用 php-fpm,因为我不知道如何让它与 SuExec 一起工作。这里没有负载平衡,只有一个 Apache 服务器接收多个网站的直接流量。 如果与 Mac OS 一起使用会更难解决问题,您必须提交错误【参考方案2】:警告与任何Fcgidxxx
选项无关,只是由于客户端在服务器有机会响应之前关闭了他们的连接。
来自实际来源:
/* Now pass any remaining response body data to output filters */
if ((rv = ap_pass_brigade(r->output_filters, brigade_stdout)) != APR_SUCCESS)
if (!APR_STATUS_IS_ECONNABORTED(rv))
ap_log_rerror(APLOG_MARK, APLOG_WARNING, rv, r,
"mod_fcgid: ap_pass_brigade failed in "
"handle_request_ipc function");
return HTTP_INTERNAL_SERVER_ERROR;
归功于Avian's Blog,他发现了这件事。
【讨论】:
【参考方案3】:当网站使用异步请求时,可能会发生此错误。这些不会直接在网页上显示为错误结果,但它们会触发 PHP 脚本的执行。如果此类脚本在执行期间失败并且不返回结果,则会记录此或类似的奇怪错误。您需要做的是识别对 PHP 脚本的 javascript (AJAX) 调用,并找出这些脚本执行失败的原因。
在等待服务器响应之前关闭连接的客户端。客户端确实正在关闭它,但它正在这样做,因为它没有收到来自 AJAX 调用的响应,这又是由网站的错误脚本引起的。
【讨论】:
以上是关于PHP 和 mod_fcgid:ap_pass_brigade 在 handle_request_ipc 函数中失败的主要内容,如果未能解决你的问题,请参考以下文章
mod_fcgid windows 命名管道 2nd 和后续请求