PHP и mod_fcgid: ошибка ap_pass_brigade в функции handle_request_ipc

Об этом было задано и ответили до qaru.site/info/385009/..., но решение для меня не работает.

mod_fcgid config

<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 script

#!/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 (Core)
  • HTTPD-2.4.6-31.el7.centos.x86_64
  • mod_fcgid-2.3.9-4.el7.x86_64
  • php56u-кли-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

Ответы

Ответ 1

Предупреждение не имеет ничего общего с параметрами 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 Blog, который узнал об этом.

Ответ 2

Я тоже получаю такую ​​же проблему примерно год назад, я пробовал много вещей, и в конце концов я сделал некоторые из хитов и запустил вещи после чтения документации, и моя проблема исчезла. Сначала важные вещи должны быть установлены как:

FcgidBusyTimeout     300 [default]
FcgidBusyScanInterval    120 [default]

Цель этой директивы - завершение работы с витыми приложениями. Может потребоваться увеличение тайм-аута по умолчанию для приложений, которые могут потребовать больше времени для обработки запроса. Поскольку проверка выполняется в интервале, определяемом FcgidBusyScanInterval, обработка запроса может быть продолжена в течение более длительного периода времени.

FcgidProcessLifeTime     3600 [default]

Ожидаемые процессы приложений, которые существовали больше, чем это время, будут прекращены, если количество процессов для класса превышает FcgidMinProcessesPerClass.

Эта проверка жизненного цикла процесса выполняется на частоте настроенного FcgidIdleScanInterval.

FcgidZombieScanInterval   3 [seconds default]

Модуль проверяет завершенные приложения FastCGI на этом интервале. В течение этого периода времени приложение может существовать в таблице процессов как зомби (в Unix).

Примечание. Все приведенные выше варианты уменьшают или увеличивают в зависимости от времени вашего приложения или потребностей или применяются к определенному vhost.

Но моя проблема решена с помощью этой опции:

Выше опции изменили мой сервер, но через некоторое время ошибки появляются снова, но ошибка действительно разрешена этим:

 FcgidOutputBufferSize   65536 [default]

Я изменил его на

 FcgidOutputBufferSize   0

Это максимальный объем данных ответа, который модуль будет считывать из приложения FastCGI, прежде чем очищать данные до клиента. Это мгновенно очистит данные, не дожидаясь 64 Кбайт байт, что действительно помогает мне быстрее очистить процесс.

Другие проблемы, которые я получил

если 500 ошибок исходит из времени Nginx. Исправление:

/etc/nginx/nginx.conf

keepalive_timeout  125;
proxy_read_timeout 125;
proxy_connect_timeout 125;
fastcgi_read_timeout 125;

С перерывами я бы получил ошибку MySQL "MySQL server has away away", которая потребовала еще одной настройки: /etc/my.conf

wait_timeout = 120

Тогда, просто для funsies, я пошел вперед и увеличил свой предел памяти PHP, на всякий случай: /etc/php.ini

memory_limit = 256M

Использование SuExec

mod_fastcgi вообще не работает под SuExec на Apache 2.x. У меня не было ничего, кроме неприятностей (у него также было много других проблем в нашем тестировании). Реальная причина вашей проблемы - SuExec

В моем случае это был запуск для меня, я начинаю Apache, mod_fcgid порождает ровно 5 процессов для каждого vhost. Теперь, когда вы используете простую загрузку script и отправляете файл размером более 4-8 КБ, все эти дочерние процессы сразу уничтожаются для определенного vhost, на котором был выполнен script.

Возможно, можно сделать отладочную сборку или запустить ведение журнала в mod_fcgid, что может дать ключ.

Я пробовал mod_fastcgi тем временем в течение 1 года, и я тоже могу сказать со многими другими, что SuExec - не что иное, как хлопотное и работает не гладко вообще, в каждом случае.