すべてのエラーは NewRelic に記録され、session_write_close
エラー ログには常にいくつかの警告が表示されていました。しかし、エラー率が増加し、24 時間ログが溢れかえっています。
当社のサーバーは人口密度が高く、多くのユーザーが同時にログインしています。これらのユーザーのほとんどはこれらのsession_write_close
警告を見ません。一部のユーザーは見るので、原因を見つけて修正することはほぼ不可能です。
完全なエラーメッセージは次のとおりです:
Error message
E_WARNING: session_write_close(): Failed to write session data (files).
Please verify that the current setting of session.save_path is correct
(/opt/php55/var/lib/php/session-nginx)
9431
そこで、そのディレクトリにファイルがいくつあり、権限が何であるかを確認しました-rw------- 1 nginx nginx
。
設定やファイル権限などに問題はないようです。
他に選択肢はありません。この問題を解決するにはどうすればいいでしょうか? 現在、ユーザーの 1% 未満に影響が出ていますが、料金をできるだけ低く抑えたいと考えています。
ここに私の php.ini 設定のリストがあります。
Directive Local Value Master Value
session.auto_start Off Off
session.cache_expire 180 180
session.cache_limiter nocache nocache
session.cookie_domain no value no value
session.cookie_httponly Off Off
session.cookie_lifetime 0 0
session.cookie_path / /
session.cookie_secure Off Off
session.entropy_file /dev/urandom /dev/urandom
session.entropy_length 32 32
session.gc_divisor 1000 1000
session.gc_maxlifetime 1440 1440
session.gc_probability 1 1
session.hash_bits_per_character 5 5
session.hash_function 0 0
session.name PHPSESSID PHPSESSID
session.referer_check no value no value
session.save_handler files files
session.save_path /opt/php55/var/lib/php/session-nginx /opt/php55/var/lib/php/session-nginx
session.serialize_handler php php
session.upload_progress.cleanup On On
session.upload_progress.enabled On On
session.upload_progress.freq 1% 1%
session.upload_progress.min_freq 1 1
session.upload_progress.name PHP_SESSION_UPLOAD_PROGRESS PHP_SESSION_UPLOAD_PROGRESS
session.upload_progress.prefix upload_progress_ upload_progress_
session.use_cookies On On
session.use_only_cookies On On
session.use_strict_mode Off Off
session.use_trans_sid 0 0
サーバー統計: CentOS 6.6、PHP 5.5.28、Nginx 1.6.2 ご協力いただければ幸いです。
答え1
負荷の高いサーバーでは、セッション ストレージにmemcached
(おそらくredis
?) を使用します。したがって、私があなたの状況であれば、おそらくそれ自体のためにそれを設定し、問題が偶然に解消されるかどうかを確認します。
また、ガベージ コレクションを Web リクエスト ジョブから切り離す PHP のセッション ガベージ コレクションも使用しません。これを処理するには、cron から実行するか、ジョブ キューイング システムから実行するかして、独自のジョブを設定します。
PHP のセッション ガベージ コレクション以外に、何らかのセッション クリーンアップ システムをすでにお持ちですか?
これが発生する割合は 0.1% で、これは設定と一致しますかsession.gc_divisor
?
PHP プロセスは nginx ユーザーとして実行されていますか? 設定に基づいてクリーンアップを実行するのは nginx ではなく php ですsession.gc_*
。PHP が nginx として実行されている場合、PHP セッション ファイルへのアクセスという点では良いのですが、ユーザー ID を nginx サーバーと共有するという点ではおそらく良くありません。
ガベージ コレクションがクリーンアップする内容を確認できるようにするには、そのセッション ディレクトリに対する実行権限が必要になる場合があります。
また、アプリケーション固有の設定を行っていない場合も心配ですsession.save_path
。つまり、複数のアプリケーションが同じセッション ディレクトリを共有している場合、ガベージ コレクションが実行されると、有効期限が最も短いアプリケーションが優先され、他のアプリケーションのセッションが消去されます。
答え2
あなたの質問から私が明らかに観察したのは、/opt/php55/var/lib/php/session-nginx にファイルを保存しようとするとボトルネックが大きすぎるということです。したがって、解決策はボトルネックを緩和し、まず何が具体的に問題なのかを診断することです。
ディスクへの書き込みが競合していて、エラーが諦めの兆候であると仮定すると、ディスクへの書き込みの問題を示す dmesg エラーが予想されます。その場合、メモリに書き込むか、またはより高速な「ディスク」に相当する他の解決策を使用できます。mc0e は
save_handle=files を使用する代わりに memcached に言及していますが、これは良いオプションです。memcached の代替として、tmpfs を使用することもできます。これは基本的にセッションをメモリ内にそのまま配置します (書き込み時間が高速です) が、新しいアプリケーションは必要ありません。
また、/opt/php55/var/lib/php/session-nginx にはどのようなファイル システムがあるかという質問もします。基本的に mktmp タイプの操作に、ext3/4 の複雑なジャーナリングは必要ありません。/tmp にフォルダーを作成し、その場所にシンボリックリンクを作成して、ファイル作成のオーバーヘッドを減らすことをお勧めします。
ハードウェアの設定はどうなっていますか? キャッシュのない単一のディスクの場合、パフォーマンスの限界に達している場合は、dmesg で問題が表示されるはずです。私はすべてのサーバーで AMCC Raid コントローラーを Raid-1 で使用しました。Raid-1 (ミラー) の場合、読み取りは高速ですが、書き込み速度は RAID の実装方法に依存します (AMCC は Raid-1 で書き込みをディスク全体に分散できることは知っていますが、すべての RAID-1 実装がそうするわけではなく、ソフトウェア RAID ではそうしないことは知っています)。私の元上司は、この理由で Raid-5 を信頼していました。実際のハードウェア RAID である限り (そうでない場合、RAID-5 は CPU に負担をかける可能性があります)、ディスク スループットが大幅に高速化されます。もう 1 つのオプションはソリッド ステート ディスクですが、実際にその方法を採用する場合は、memcached または tmpfs を使用することをお勧めします。メモリを増やすことは常に良い計画です (他の新しいハードウェアよりも)。
最も簡単な解決策は、/tmp/session-nginxを作成し、/opt/php55/var/lib/php/session-nginxを/tmp/session-nginx/にシンボリックリンクまたはマウントすることです。
答え3
質問の一部は、そのような種類のエラーを追跡するのが難しいということに関するものです。そのため、try/catch ブロック内のコードでセッションを明示的に閉じることをお勧めします。例外を処理し、スリープしてから再試行してください。
質問のその他の部分では、ランダムな性質の書き込みエラーについて説明しています。これは、不正な権限から発生するとは予想されません。開いているファイルが多すぎるのではないかと思います。
何が起こるかを確認するために、いくつかの設定を微調整します。
オープンファイルの制限を増やすOS の一部に下限値が設定されている可能性があります。たとえば、私のノートブックは数十万のファイルを開くことをサポートしていますが、同じユーザーからのファイルは 4000 個のみです。
maxrequestperchildsを1000に下げるこれにより、各 http サーバーは 1000 台のクライアントにサービスを提供した後に再起動します。
MaxClientsを減らすそしてListenBacklogを増やすこれは非常に直感に反しますが、MaxClients/Servers を高く設定しすぎると、多くのプロセスがサーバー内のリソースを奪い合い、ボトルネックが発生します。これは、ボトルネックの種類によって大きく異なります。私の場合は、データベース サーバーです。