先月末に2日~3日ほど当ブログで閲覧障害が発生していた件についての備忘録。
本来は解決後すぐに記事を書いておくべきだったのだが、面倒で放置されていたので記憶が曖昧になっているためチャットログを纏める形になる。
環境
問題が発生した当時のもろもろの環境
- カゴヤVPS OpenVZの一番安いプラン
- Debian GNU/Linux Jessie
- OpenLiteSpeed 1.4
- lsphp7
障害
11月26日
ふとブログにアクセスしたときページが表示できなかった。
当ブログのメンバーに聞いてみたところ、何故か他の人は普通にアクセスできているようだったが、色々ためした結果、自分はChromeでは表示できなくてFirefoxでは表示できるというわけわからないことになっていた。
上記の現象が他のメンバーにも及び、「プライベートモードでは見られる」だとか、「俺はプライベートモードでもダメだ」とか、「プライベートモードでもダメになった」とかわけわからない事になった。
アクセスカウンタのPVも目に見えて減っていることから対策を決意。
tracertとpingは問題なかったことや、テキストファイルへのアクセスは正常だったことからPHP(lsphp7)周りにあたりをつけた。
OpenLiteSpeedのエラーとして503が確認された。
OpenLiteSpeedの再起動によって一瞬解決したかに見えたが、ウェブ管理画面のページが再起動後に再度ログインしなおすまで404になる謎の現象が起きる。
解決したかのように見えた503問題も少し時間が立てば元に戻ってしまった。
11月27日
OpenLiteSpeedのログの1つに見慣れない「stderr.log」なるものが出来ていた。
中身は主に2つのエラーで占められていた。
- [INFO] Process with PID: 24815 is dead
- Fatal Error Unable to allocate shared memory segment of 134217728 bytes: mmap: Cannot allocate memory (12)
2つ目のエラーから考えるに、大きなメモリを確保しようとして失敗しているように見られる。
前科のあるWordPressプラグインの暴走を考えて全てのプラグインを停止してサーバーを再起動しても直らなかった。
WordPressプラグインを本命視していたのでこの辺りにかなり時間を喰わされた。WPのソース読んだりとか。
ページが環境によって見られたり見られなかったりする点から、PHPがマルチプロセスで、死んでるプロセスに振り分けられると見られない説が浮上。
案の定OpenLiteSpeedのPHP(lsphp7)はデフォルトでマルチプロセスだった。
11月28日
システムの共有メモリを調べるコマンドを実行したところ、システムの共有メモリの上限を超えていたことがわかった。
[bash]
cat /proc/user_beancounters
[/bash]
lsphp7が別プロセスかどうかを調べたところ別プロセスだった。
メモリを割り当てられないエラーの値(134217728)はphp側の設定の上限値と同一だったので、そこを変更してみた。
まずphp.iniでmemory_limitの値を変更したのだが、再起動しても変化が見られなかった。
そこでopcacheのメモリ上限(opcache.memory)を128MBから256MBに引き上げたところ、stderr.logに出力されるメモリが確保できないエラーの値が134217728から268435456に変更された。
(opcache周りの設定はデフォルトでコメントアウトされていたため、メモリ上限を引き上げるならコメントアウトを外して引き上げるのはもちろん、;opcache.enable=1のコメントアウトも外す必要がある)
次にopcacheを無効にしてみたところ、表示速度は体感でわかるほど遅くなったものの、stderr.logへのエラー出力は止まり、サーバーとしては安定した。
何がそうさせているかはさておき、何かがlsphp7のOPCache memoryを大量に割り当てようとしてシステムの共有メモリの上限を超えていたことがわかった。
/tmpは共有メモリと同じでメモリ割り当てなので、OS自体の共有メモリが上限に達して/tmp/以下へのファイルの作成・書き込みが出来なくなった説が出る。
そこでtopコマンドで共有メモリ(SHR)の使用量を調べたところ、OPCacheが無効状態でもlsphpのプロセス郡が最もSHRを消費していることがわかった。
最初はlsphpのメモリリークが疑われたが、別環境での検証の結果、lsphpの再起動直後でもOPCacheが有効であれば1プロセスあたり数万のSHRを消費してもおかしくない事がわかった。
原因
結論として、ただでさえ共有メモリを大きく消費する(しうる)lsphpのプロセスが増え過ぎたせいでシステムの共有メモリが限界に達して正常に動作できなかったということになった。
OpenLiteSpeedの管理画面を見ると、デフォルトで35プロセスまでの起動が許可されているにも関わらず、今回の環境では7プロセス程度で限界近くなっていた。
ようするに単なるリソース不足だと思う。
ただし、これまで正常に動いていた中で、どうして急にこの問題が発生したのか?という所は結局謎のままになっている。
解決
OpenLiteSpeedのPHP_LSAPI_CHILDREN項目の値を4に制限した。
現状4プロセス制限でも当ブログの表示速度に体感上の影響は見られない。
解決といって良いと思う。
コメント