Необычные ответы 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.