今回はWebシステム障害におけるトラブルシューティングの、とある一場面を紹介します。日々発生するトラブルの内容と対処方法は千差万別です。あらゆるトラブルに対応できるトラブルシューティング手法というものは残念ながら世の中に存在しませんが、どんなトラブルにおいても疑わしい個所を1つずつ潰していくといずれ障害原因にたどり着きます。本稿ではそんなトラブルシューティングの現場の雰囲気を簡単に紹介できればと思います。
トラシュー事例(初級編)
「特定Webサーバだけレスポンス低下」
図1 のようなWebシステムにおいて、Web5サーバだけレスポンスが低いようだという連絡を受けたとします。この場合、何をどう調べていけばよいでしょうか?
図1 Webシステム構成図
前提として、各Webサーバは次のような構成になっているとします。
CPU:4core 1.86GHz
RAM:4GB
HDD:SAS 300GB×2(RAID1)
NIC:1Gbps
OS:CentOS6.6 64bit
Web:Apache2.4.12
言語:PHP5.5.0
また各ネットワーク機器はアップリンク側、サーバ側がともに1000BASE-Tのポートを持っており、いずれもAuto negotiationで設定されているとします。
トラフィック量を見る
まずはネットワークのトラフィック量を示すグラフを見てみます。図2 にてWeb5サーバと正常なサーバとを比較してみると、Web5サーバは70Mbpsあたりで頭打ちに見えますが、正常なサーバでは右側のように120Mbps程度まで使われていることがわかります。
図2 トラフィック量のグラフ
サーバのハードウェアリソース使用状況を見る
次に、サーバのハードウェアリソース使用状況を見てみます。調べ方はいろいろありますが、図3 のようにvmstatコマンドを使って調べてみることにします。結論から言うとハードウェアリソース的にはまだ十分余裕がある状況と言えます。
図3 ハードウェアリソース使用状況
CPUは、Procsのr(実行キューに入っている実行待ちプロセス数)がなく、CPU使用率もidle率が99%、すなわち1%ほどしか使われていないというかなり余裕がある状況
ディスクI/Oはほとんど発生していない状態
メモリもかなり余裕がある状況
メモリは物理容量4GBに対して、未使用メモリ量(free)が約25MB、バッファキャッシュ[1] に使用されているメモリ量(buf)が約68MB、そしてページキャッシュ[2] として使用されているメモリ量(キャッシュ)が3,086MBとなります。こう書くと未使用領域がわずか25MBしか残ってないと思ってしまうかもしれませんが、メモリが足りなくなってきたらOSはバッファキャッシュやページキャッシュからメモリを割り当てるため、実際はまだ3GB以上のメモリが使える状況と読み取ることができます。
以上のことからハードウェアリソース使用状況としてはとくに問題ない状況と言えます。
ネットワークまわりを確認する
L2スイッチのステータス情報を見てみると、Web5とつながるポートだけが100M Halfと認識され、それ以外のポートは1,000M Fullと認識されていました。
そこでそれぞれの通信モード設定を確認してみると、Web5サーバだけが100M Full固定で設定されていたのに対し、それ以外のWebサーバはAuto negotiationで設定されていることがわかりました。
ここで2つの疑問が浮かびます。1つめはなぜ1,000M Fullではなく100M Full固定で設定されていたのか。2つめはなぜサーバ側は100MFull固定なのにL2スイッチ側では100M FullではなくHalfで認識されたのか。これらについてちょっと考えてみましょう。
1つめについては、1000BASE-TはそもそもAuto negotiationで使うよう規定されているので1,000M Full固定という設定自体が行えません(試しにL2スイッチやLinuxなどでネットワークインターフェースを1,000M Full固定で設定してみてください。エラーが出て設定できないはずです) 。今回Web5サーバを設定した人は、おそらく1,000M Full固定設定をしようとしてうまくいかず、いろいろ試しているうちに誤って100MFull固定で設定して安心してしまったものと推測されます。
2つめについては、よくありがちな誤解として、片側が100M Full固定で設定されている場合、Auto negotiationが設定されている側では自動的に100Mbps Fullとして認識してくれそうな気がします。しかし実際は100Mbps Halfで自動設定されるため通信モードの不一致が発生します。
図4 を見てみましょう。双方がAuto negotiationで設定されると、お互いがFLP(Fast Link Pulse)バーストという信号を投げ合って通信モードを決定します。しかし相手からFLPバースト信号が返ってこない場合は、10BASE-T対応機器が発信するNLP信号(Normal Link Pulse)や100BASE-TX対応機器が発するアイドル信号を検出することで、10BASE-Tか100BASE-TXのいずれかと判断されます。ただしこの場合FullとHalfまでは判断できず、必ずHalfとなります。
図4 通信モードが一致しない
この結果、なんとか通信はできるものの大量の通信エラーが発生するだけでなく、帯域が100M Halfや10M Halfなどに制限されることになります。このような事象を防ぐためにネットワーク機器とサーバの通信モード設定は100M固定なら双方100M、Auto negotiationなら双方Auto negotiationに一致させる必要があります。
ということで、今回の場合はサーバ側もAutonegotiationに設定し直すことで、システムが正常な状態に戻りました。
なお蛇足ですが、双方Auto negotiationにしても、通信モードが一致しないことがまれに発生します。この場合はLANケーブル不良を疑い、新しいものに交換すると直ることが経験上多いです。
トラシュー事例(上級編)
「Web全体のレスポンスが不安定」
今度は、Web全体のレスポンスが不安定な状況を想定してみます。今回はとくにどのサーバのレスポンスが低下したということはなく、システム全体でレスポンスが低下しているとします。そこで先ほどの事例を参考にしてL2スイッチ/全サーバの通信モードを確認してみましたが、設定がすべてAuto negotiationに統一されていました。
今回は特定サーバだけが問題ではなさそうですので、ネットワークまわりを疑ってみることにします。
ファイアウォールを確認する
まずはDDoS(Distributed Denial of ServiceAttack)攻撃と呼ばれる、サービス妨害のために不特定多数のマシンから大量のパケットが送信される状況がなかったか確認します。そこでファイアウォールのログなどを確認しましたが、今回はとくにそのような攻撃は受けた跡はありませんでした。
L2スイッチを確認する
次にL2スイッチのログを見てみます。ここではバッファが溢れることで通信を一部取りこぼしていることを示す状況が確認できました。
一般的なL2スイッチでは、図5 のように受信したフレームをいったんバッファに入れてから少しずつ転送するしくみを取ります。このバッファが溢れたとなると短時間に大量のパケットやフレームがスイッチに流入したのだと推測されます。バッファに収まらないほどのフレームを受け取るとそのフレームは破棄され、結果的に通信が不安定になります。
図5 スイッチのバッファが溢れる
PCからスマートフォンの時代変化に伴い、ものすごく小さいパケットサイズの通信が大量に発生するようになり、ユーザ数がとくに多いサービスにおいては、L2スイッチのバッファサイズが足りなくなる状況が見られるようになりました。
このような場合には、バッファサイズの大きいL2スイッチに入れ替えるか、もしくはL2スイッチを増設して負荷を分散することが有効です。
最後に
トラブルシューティングの場面に遭遇したとき、一度経験したことのあるトラブルであれば容易に原因がつかめますが、実際は初めて遭遇するトラブルに出会う場面も多いでしょう。そんなときに必要となるのはあらゆる可能性を疑って根気強く原因を探すことです。
無論、現実的にはサービス復旧が最優先され、まずはリブートすることが求められる場面も多々あるかと思います。しかしトラブル発生のたびに原因究明する習慣をつけないと、いつまで経ってもトラブルシューティング力が向上しません。もしサービス復旧のためのリブートが要求されるのであれば、あとでトラブル分析ができるように各種ログ、画面イメージ、そのほか何でもいいので証拠となりそうなものを一通り収集してからにしましょう。
第1特集
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識
第2特集
「知りたい」「使いたい」「発信したい」をかなえる
OSSソースコードリーディングのススメ
特別企画
企業のシステムを支えるOSとエコシステムの全貌
[特別企画]Red Hat Enterprise Linux 9最新ガイド
短期連載
今さら聞けないSSH
[前編]リモートログインとコマンドの実行
短期連載
MySQLで学ぶ文字コード
[最終回]文字コードのハマりどころTips集
短期連載
新生「Ansible」徹底解説
[4]Playbookの実行環境(基礎編)