Apache 2.4 イベント MPM + php-fpm + php-opcache で「ピアによる接続のリセット」エラーが発生する

Apache 2.4 イベント MPM + php-fpm + php-opcache で「ピアによる接続のリセット」エラーが発生する

CentOS 7 サーバーで、Event MPM と php-fpm バージョン 5.6.10 (REMI リポジトリから) を搭載した Apache 2.4.6 を実行しています。vhost 内の php-fpm にリクエストを送信するための関連する Apache 構成は次のとおりです (これはこのサーバー上の唯一のサイトです)。

<FilesMatch \.php$>
    SetHandler "proxy:unix:/var/run/php-fpm/www.sock|fcgi://localhost"
</FilesMatch>

関連する php-fpm プール conf は次のとおりです。

listen = /var/run/php-fpm/www.sock
listen.owner = apache
listen.group = apache
pm = static
pm.max_children = 50
pm.max_requests = 0

php-opcache の設定(デフォルトのインストール設定)は次のとおりです。

zend_extension=opcache.so
opcache.enable=1
opcache.memory_consumption=128
opcache.max_accelerated_files=4000
opcache.blacklist_filename=/etc/php.d/opcache*.blacklist

私の問題:php-opcache をインストールして有効にすると、エラー ログに次のエラーが表示されるようになります。

[Thu Jun 18 08:10:58.499871 2015] [mpm_event:debug] [pid 16546:tid 139798115227392] event.c(986): (104)Connection reset by peer: [client 157.55.39.233:15962] AH00470: network write failure in core output filter
[Thu Jun 18 08:10:58.527424 2015] [mpm_event:debug] [pid 16546:tid 139797922195200] event.c(986): (103)Software caused connection abort: [client 157.55.39.233:15990] AH00470: network write failure in core output filter

php-opcache を削除すると、エラーは発生しなくなります。これが発生するたびに、ユーザーはフロントエンドで 502 Service Unavailable エラーを報告しています。

私は文字通り少なくとも 6 時間を Google で検索して解決策を見つけようとしました。誰かが opcache のfastshutdownオプションが問題だと言っていましたが、これはデフォルトの設定では無効になっています。php-fpm プロセス管理方法をリサイクルなしの静的 (max_requests=0) に変更しましたが、それでも何も変わりませんでした。また、Apache で TCP プロキシ メソッド (ソケットの代わりに) を使用することも試しましたが、これも効果はありませんでした。

これが関連しているかどうかはわかりませんが、php-opcache がインストールされているかどうかに関係なく、エラー ログに次のエラーが報告されます (ただし、頻度は非常に低く、全トラフィックの 0.5% 未満であるため、別の問題である可能性があります)。

[Thu Jun 18 08:32:37.223430 2015] [proxy_fcgi:error] [pid 19187:tid 140598765840128] [client 37.46.115.238:55624] AH01068: Got bogus version 10, referer: ...
[Thu Jun 18 08:32:37.223462 2015] [proxy_fcgi:error] [pid 19187:tid 140598765840128] (22)Invalid argument: [client 37.46.115.238:55624] AH01075: Error dispatching request to :, referer: ...

この問題は、これですただし、その人は TCP メソッドで ProxyPassMatch を使用していますが、私はそうではありません (.htaccess をバイパスするため)。

私がまだ言及していないアイデアを持っている人はいますか?

答え1

私たちの環境で同様の問題を見たとき、それは共有ホスティング環境上のすべてのユーザー間で OpCache (デフォルト) が単一のキャッシュを共有する方法によるものだったようです。バグが提出されました(そして、投票してメンテナーにこれがあなたのユースケースにとってどれほど重要であるかを知らせることもできますし、そうすべきです) ただし、修正を提供するという約束はありません。

TL;DR: OpCacheが有効になっている場合、デフォルトでは、コンパイルされたバイトコードを保存するために使用されるキャッシュはすべてのユーザー間で共有されます。ホスティングが複数のサイト/ユーザー間で共有されている環境では、これにより、サイトが別のサイトからキャッシュされたPHPスクリプトの出力を取得したり、特定のセキュリティ設定が有効になっている場合はエラーが発生したりする可能性があります。

PHP 5.5 以降に組み込まれている opcache で PHP-FPM を使用する予定の場合は、実際に実行する前に、以下のブログ記事をお読みください。opcode キャッシュは、サーバー上のどのユーザーでも読み取ることができることが判明しました。つまり、たとえば、独自の vhost とディレクトリを持つ 10 人のユーザーがいて、ユーザーごとに 1 つの PHP-FPM プールを構成した場合、各ユーザーは、キャッシュされているスクリプトとその場所を確認できます。キャッシュへの読み取りアクセス権があるため、このすべてのデータを表示できる可能性があります。

これは明らかにセキュリティ上の大きな懸念事項であり、たとえ誰もこれを悪用しなかったとしても、ページを生成するときに間違ったユーザーによってスクリプトが読み取られる可能性が依然として残ります。そのため、キャッシュ内に複数の index.php スクリプトがある場合、Web サイトが間違ったデータや情報を表示する可能性があります。

公式には修正はリリースされていませんが、cPanelを使用している場合は、このウィキには、ユーザーごとに作成および保護されるphp-fpmプールを構成する方法が文書化されています。以下の指示に従ってください。重要な注意事項この回答の下部では、エラーなしで必要な機能を取得できるはずです

この投稿では、サイトごと/ユーザーごとに手動で設定する方法も説明されています (ただし、多数のサイトをホストしている場合は面倒になると思います)。cPanel を使用していない場合は、cPanel の設定エンジンで使用されている変数ではなく、個別のパスとユーザー名を指定するようにスクリプトを変更する必要がある場合があります。


重要な注意事項

テストと追加の調査中に私はこの記事はいくつかの説明を提供しているあなたの特定の状況に関係するかもしれないもの:

  1. アプリケーションの OpCache 構成のopcache.use_cwdパラメータが に設定されていることを確認する必要があります。これはデフォルトで に設定されており、システム上で複数の PHP アプリケーションをホストしている場合、デフォルトのままにしておくと衝突が発生する可能性があります。truefalse

まず、おそらく各典型的なプロジェクトでは、opcache.use_cwd オプションが true に設定されていることを確認する必要があります。この設定を有効にすると、OpCache エンジンは完全なファイル パスを調べて、同じ名前のファイルを区別します。これを false に設定すると、同じベース名を持つファイル間で衝突が発生します。

  1. Zend Framework または注釈を使用する他の同様のフレームワークを搭載したアプリケーションを実行している場合は、opcache.load_commentsおよびopcache.save_commentsディレクティブが に設定されていることも確認するtrue必要があります。ほとんどのアプリケーション/フレームワークのドキュメントでは、システムで OpCache を適切に使用するための具体的な手順が記載されたドキュメントが更新されているため、この提案をアプリケーション/フレームワークのドキュメントで再確認する必要があります。

また、注釈を使用するツールやフレームワークでは重要な設定があります。Doctrine、Zend Framework 2、または PHP Unit を使用する場合は、opcache.load_comments および opcache.save_comments 設定を true に設定することを忘れないでください。その結果、ファイルのドキュメント コメントも OpCache によって生成されたプリコンパイル済みコードに含まれます。この設定により、中断することなく注釈を操作できます。

プロジェクトが特定のフレームワークまたはWebアプリケーションに基づいている場合は、OpCache構成に関するガイドラインについてドキュメントを確認することをお勧めします。

重要な注意事項


これがお役に立てば幸いです。cPanel を使用している場合は、コメントを残して、構成のその部分にどのように対処したかをお知らせください。 この質問と関連するコメントも参照してください

関連情報