PHP и mod_fcgid: сбой ap_pass_brigade в функции handle_request_ipc

Об этом спрашивали и отвечали до /questions/7332624/modfcgid-sboj-appassbrigade-v-funktsii-handlerequest/7332632#7332632 но решение там не работает для меня.

Конфигурация 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 (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

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, который узнал об этом.

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

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 ушел", что потребовало еще одного изменения:/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 процессов для каждого vhost. Теперь при использовании простого сценария загрузки и отправки файла размером более 4-8 КБ все эти дочерние процессы сразу уничтожаются для конкретного vhost, на котором выполнялся сценарий.

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

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

Эта ошибка может возникать, когда веб-сайт использует асинхронные запросы. Они не отображаются напрямую как ошибочный результат на веб-странице, но запускают выполнение сценариев PHP. Если такие скрипты терпят неудачу при выполнении и не возвращают результата, эта или подобные странные ошибки регистрируются. Что вам нужно сделать, так это идентифицировать вызовы JavaScript (AJAX) ваших сценариев PHP и выяснить, почему выполнение этих сценариев не выполняется.

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

Другие вопросы по тегам