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

Sla*_*rix 17 php linux apache mod-fcgid

/sf/answers/888037671/之前已经问过并回答了这个问题,但是,那里的解决方案对我不起作用.

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>
Run Code Online (Sandbox Code Playgroud)

php-cgi脚本

#!/bin/bassh
export PHPRC=/var/www/vhosts/example.com/etc/
export PHP_FCGI_MAX_REQUESTS=5000
exec /usr/bin/php-cgi
Run Code Online (Sandbox Code Playgroud)

系统细节

  • 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设置为10x,如前面的答案和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
Run Code Online (Sandbox Code Playgroud)

Vin*_*982 16

一年前我也遇到了同样的问题然后我尝试了很多东西,最后我在文档阅读后完成了一些命中和运行,我的问题就消失了.首先需要设置的重要事项是:

FcgidBusyTimeout     300 [default]
FcgidBusyScanInterval    120 [default]
Run Code Online (Sandbox Code Playgroud)

该指令的目的是终止挂起的应用程序.对于可能需要更长时间来处理请求的应用程序,可能需要增加默认超时.因为检查是在定义的时间间隔执行的,所以FcgidBusyScanInterval可以允许请求处理进行更长的时间段

FcgidProcessLifeTime     3600 [default]
Run Code Online (Sandbox Code Playgroud)

如果该类的处理次数超过,则将终止已存在超过此时间的空闲应用程序进程FcgidMinProcessesPerClass.

此过程生命周期检查以配置的频率执行FcgidIdleScanInterval.

FcgidZombieScanInterval   3 [seconds default]
Run Code Online (Sandbox Code Playgroud)

模块以此间隔检查退出的FastCGI应用程序.在这段时间内,应用程序可能作为僵尸存在于进程表中(在Unix上).

注意:以上所有选项根据您的应用程序处理时间或需求减少或增加或适用于特定的vhost.

但我的问题通过此选项解决:

上面的选项调整了我的服务器,但一段时间后错误似乎再次出现,但错误实际上解决了这个:

 FcgidOutputBufferSize   65536 [default]
Run Code Online (Sandbox Code Playgroud)

我把它改成了

 FcgidOutputBufferSize   0
Run Code Online (Sandbox Code Playgroud)

这是在将数据刷新到客户端之前,模块将从FastCGI应用程序读取的最大响应数据量.这将立即刷新数据而不等待64KB的字节,这真的有助于我更快地清除进程.

我得到的其他问题

如果500错误来自Nginx超时.修复:

/etc/nginx/nginx.conf

keepalive_timeout  125;
proxy_read_timeout 125;
proxy_connect_timeout 125;
fastcgi_read_timeout 125;
Run Code Online (Sandbox Code Playgroud)

间歇性地我会得到MySQL"MySQL服务器已经消失"的错误,这需要再调整一次: /etc/my.conf

wait_timeout = 120
Run Code Online (Sandbox Code Playgroud)

然后,为了好玩,我继续并提高了我的PHP内存限制,以防万一: /etc/php.ini

memory_limit = 256M
Run Code Online (Sandbox Code Playgroud)

使用SuExec

mod_fastcgi没有所有下,在工作SuExecApache 2.x.我只有麻烦(它在我们的测试中还有许多其他问题).问题的真正原因是SuExec

在我的情况下,这是一个初创公司,我启动Apache,mod_fcgid为每个vhost产生5个进程.现在,当使用简单的上载脚本并提交大于4-8KB的文件时,对于执行脚本的特定vhost,所有这些子进程都会被立即终止.

有可能在mod_fcgid中进行调试构建或启动日志记录,这可能会给出一些线索.

我在此期间尝试了mod_fastcgi 1年,我也可以和其他许多人说SuExec只是麻烦而且运行不顺畅,无论如何.


aef*_*fxx 5

该警告与任何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;
}
Run Code Online (Sandbox Code Playgroud)

归功于Avian的博客,他发现了这一点。