PHP 和 mod_fcgid:ap_pass_brigade 在handle_request_ipc 函数中失败

问题描述 投票:0回答:3

这已经被问过并回答过https://stackoverflow.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
php linux apache mod-fcgid
3个回答
23
投票

大约一年前我也遇到了同样的问题,当时我尝试了很多事情,最后我在阅读文档后做了一些即兴运行的事情,我的问题消失了。首先需要设置的重要事项为:

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 的文件时,对于执行脚本的特定虚拟主机,所有这些子进程都会立即终止。

也许可以在 mod_fcgid 中进行调试构建或启动日志记录,这可能会提供线索。

我同时尝试了 mod_fastcgi 一年,我也可以和其他许多人一起说,SuExec 只不过是麻烦,而且在任何情况下都运行得不顺利。


16
投票

该警告与任何

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 博客


0
投票

网站使用异步请求时可能会出现此错误。这些不会直接在网页上显示为错误结果,但它们会触发 PHP 脚本的执行。如果此类脚本在执行期间失败并且不返回结果,则会记录此错误或类似的奇怪错误。您需要做的是识别对 PHP 脚本的 JavaScript (AJAX) 调用,并找出这些脚本执行失败的原因。

在等待服务器响应之前关闭连接的客户端。客户端确实正在关闭它,但它正在这样做,因为它没有收到 AJAX 调用的响应,而这又是由网站的错误脚本引起的。

© www.soinside.com 2019 - 2024. All rights reserved.