Необычные ответы Apache PHP-FPM с прокси enablereuse=on

При включении <Proxy ... enablereuse=on max=10> Я начинаю получать странные ответы. При обновлении текущей страницы основной запрос загружает разные ответы; как пустая страница, ответы, предназначенные для отдельного клиента, или ответ 404 из файла CSS на запрошенной странице.

Удаление enablereuse, исправляет странные ответы, но предотвращает одновременные запросы от одного и того же пользователя, то есть каждый запрос обрабатывается индивидуально.

Например: при открытии двух вкладок браузера для двух разных URL-адресов в одном и том же домене vhost. Если для загрузки первой запрошенной страницы требуется 5 секунд, вторая вкладка не будет загружена, пока не будет завершена первая.

Я пытаюсь предотвратить это, позволяя одному и тому же клиенту одновременно выполнять несколько запросов, не блокируя их.

Серверная среда

CentOS 6.10 x64
php 5.6.37 Remi
Apache 2.4.33 IUS

Конфигурация события MPM

<IfModule mpm_event_module>
    ServerLimit              100
    StartServers             4
    ThreadLimit              64
    MaxRequestWorkers        100
    MinSpareThreads          25
    MaxSpareThreads          75
    ThreadsPerChild          25
    MaxConnectionsPerChild   1000
    ListenBacklog       511
</IfModule>

Конфигурация виртуального хоста (1 из 4 - все идентичные, кроме IP-адреса, UDS и ServerName)

<VirtualHost 192.168.1.71:443>
    ServerName example.com:443
    DocumentRoot /home/example/example.com
    <IfModule mod_ssl.c>
        SSLEngine on
        SSLCertificateFile /etc/httpd/ssl/certs/example.crt
        SSLCertificateKeyFile /etc/httpd/ssl/private/example.key
        SSLCertificateChainfile /etc/httpd/ssl/certs/example.ca-bundle
        <IfModule mod_setenvif.c>
            SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1
        </IfModule>
        <IfModule mod_headers.c>
            Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
        </IfModule>
    </IfModule>
    <Directory "/home/example/example.com">
        AllowOverride All
        Require all granted
    </Directory>
    <IfModule mod_proxy_fcgi.c>
        <FilesMatch \.php$>
            <If "-f %{REQUEST_FILENAME}">
                SetHandler "proxy:unix:/var/run/example.sock|fcgi://127.0.0.1/"
            </If>
        </FilesMatch>
        <Proxy "fcgi://127.0.0.1" enablereuse=on max=10>
            ProxySet timeout=7200
        </Proxy>
    </IfModule>
</VirtualHost>

Конфигурация пула PHP-FPM (1 из 4, все идентичные, кроме UDS)

[example_com]
user = example
group = example
listen = /var/run/example.sock
listen.owner = example
listen.group = apache
listen.mode = 0660

pm = dynamic
pm.max_children = 20
pm.start_servers = 2
pm.min_spare_servers = 2
pm.max_spare_servers = 20
pm.max_requests = 1000

security.limit_extensions = .php

Я пытался использовать TCP-прокси, а не UDS из-за других сообщений, комментирующих проблемы с UDS, которые не поддерживаются, но проблема сохраняется:

<IfModule mod_proxy_fcgi.c>
    <FilesMatch \.php$>
        <If "-f %{REQUEST_FILENAME}">
            SetHandler "proxy:fcgi://127.0.0.1:9000/"
        </If>
    </FilesMatch>
    <Proxy "fcgi://127.0.0.1:9000" enablereuse=on max=10>
        ProxySet timeout=7200
    </Proxy>
</IfModule>

Также попытался изменить конфигурацию PHP-FPM с PM, установленным в dynamic, ondemand а также static с соответствующими изменениями процесса.


Я определил, что ограничение одновременных запросов было связано с PHP-сессиями и блокировкой, которая накладывается на сессии на основе файловой системы. Однако проблема не соответствует странным ответам, которые я получил.

1 ответ

Из документации Apache 2.4: Разрешить повторное использование соединения с бэкэндом FCGI, таким как PHP-FPM

Пожалуйста, имейте в виду, что PHP-FPM (на момент написания, февраль 2018 года) использует модель prefork, а именно каждый из его рабочих процессов может обрабатывать одно соединение одновременно. По умолчанию mod_proxy (настроенный с помощью enablereuse=on) разрешает пул соединений ThreadsPerChild с бэкендом для каждого процесса httpd при использовании потокового mpm (например, работника или события), поэтому следует учитывать следующие варианты использования:

Under HTTP/1.1 load it will likely cause the creation of up to MaxRequestWorkers connections to the FCGI backend.
Under HTTP/2 load, due to how mod_http2 is implemented, there are additional h2 worker threads that may force the creation of other backend connections. The overall count of connections in the pools may raise to more than MaxRequestWorkers.

Максимальное количество рабочих процессов PHP-FPM необходимо настраивать с умом, поскольку существует вероятность того, что все они в конечном итоге будут "заняты" обработкой постоянных бездействующих соединений без возможности установки новых, и опыт конечного пользователя будет быть кучей тайм-аутов HTTP-запросов.

Так что мое упоминание не использовать enablereuse с mod_proxy_fcgi + php-fpm.

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