При включении <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 и блокировкой, налагаемой на сеансы на основе файловой системы. Однако проблема не соответствует полученным мной странным ответам.
Из документации Apache 2.4: включить повторное использование подключения к бэкэнду FCGI, например PHP-FPM
Имейте в виду, что PHP-FPM (на момент написания, февраль 2018 г.) использует модель prefork, а именно, каждый из его рабочих процессов может обрабатывать одно соединение за раз. По умолчанию mod_proxy (настроенный с помощью enablereuse = on) разрешает пул соединений ThreadsPerChild подключений к бэкэнду для каждого процесса httpd при использовании многопоточного mpm (например, worker или event), поэтому следует учитывать следующие варианты использования:
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.