<Proxy ... enablereuse=on max=10>
を有効にすると、奇妙な応答を受け取り始めます。現在のページを更新すると、メインリクエストはさまざまな応答をロードします。空白のページ、別のクライアント向けの応答、または要求されたページのCSSファイルからの404応答のように。
enablereuse
を削除すると、奇妙な応答が修正されますが、同じユーザーからの同時リクエストは防止されます。つまり、各リクエストは個別に処理されます。
たとえば、2つのブラウザタブを同じvhostドメインの2つの異なるURLで開くと、最初に要求されたページの読み込みに5秒かかる場合、最初のタブが完了するまで2番目のタブは読み込まれません。
同じクライアントが複数のリクエストを同時に非ブロッキング方式で実行できるようにすることで、これを防止しようとしています。
サーバー環境
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、サーバー名を除いてすべて同一)
<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プール構成(4つのうち1つは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
UDSがサポートされていない問題についてコメントしている他の投稿があるため、UDSではなくTCPプロキシを使用しようとしましたが、問題は解決しません。
<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>
また、適切なプロセス変更を使用して、pmをdynamic
、ondemand
、およびstatic
に設定してPHP-FPM構成を変更してみました。
同時リクエストの制限は、PHPセッションと、ファイルシステムベースのセッションに課せられたロックによるものであると判断しました。ただし、この問題は、受け取った奇妙な応答とは一致しません。
ドキュメントからApache2.4:PHP-FPMなどのFCGIバックエンドへの接続の再利用を有効にする
PHP-FPM(執筆時点では2018年2月)はプリフォークモデルを使用していること、つまり、各ワーカープロセスが一度に1つの接続を処理できることに注意してください。デフォルトでは、mod_proxy(enablereuse = onで構成)は、スレッド化されたmpm(ワーカーやイベントなど)を使用するときに、各httpdプロセスのバックエンドへのThreadsPerChild接続の接続プールを許可するため、次のユースケースを考慮する必要があります。
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リクエストのタイムアウトの山になります。
したがって、私の言及では、mod_proxy_fcgi + php-fpmでenablereuseを使用しないでください。