こんにちは。スタメンの 小林 ( @lifework_tech )です。 スタメンの社内勉強会で障害対応について話しましたので、資料を公開させていただきます。
障害対応への考え方と備え
どんなに対策を行っていても障害は必ず発生します。地震のようにいつ発生するのかはわかりません。でも、予め障害発生を想定して、準備しておくと、影響の低減、復旧までの時間短縮など多くのメリットがあります。
障害に向き合い再発防止策を積み重ねることで、システムもチームも強くなることを目指し、普段意識していることをまとめてみました。
障害の検知から対応まで
障害を把握したら
- まずは落ち着く
障害を知ったらまずは深呼吸して落ち着きましょう。慌てて対応してもいいことは何もありません。
- 役割を分担する
原因調査をしつつ、応急処置を行い、社内に連絡するなど、障害対応は同時並行で進みます。また、普段のデバッグと一緒で、一人よりも、誰かと話しながら対応すると、スムーズに進むものです。
まずはチームメンバーに連絡を取り障害対応を分担できるようにしましょう。
原因を把握する
アラートや社内からの報告など、障害を把握することになった情報があるはずです。まずは、その情報を起点として何が起きているかを把握することが大事です。
このときアラート、ログを精査することが多いと思いますが、「原因」と「現象」を意識することが大事です。
例えば、AWS の CloudWatch ALARM を用いて監視を行っている場合、Elastic Load Balancing (ELB) の HTTP応答の Latency が しきい値 を超えたというアラートによって、障害発生を知ることがあります。この場合、何らかの原因があって、ELB の遅延が発生しているのであって、現象としての負荷に対応しようとして、サーバーを増設しても「原因」は解消されません。
また、MySQL への接続数が上限に達したときに発生する Too many connections の場合、Rails 等の クライアント から 新たに接続できないのは「現象」であって、滞留しているクエリなど接続数を増やす「原因」は別にあります。
なので、「この現象を起こしている要因は何か?」と考えながら、ログやアラートを見ると良いです。
また、それぞれのログには非常に重要な情報が含まれています。なんとなく流し読みするのではなく、一つ一つメッセージ (エラー) の意味を理解しながら調査してください。
加えて、時系列にメモを取りながら調査すると、状況の整理、チームへの共有、障害報告への記載などに役立ちます。テキストエディタ でも良いですし、Slack 等のチャットへ貼っていくのでも良いでしょう。
こういうときに、MySQL や bash/zsh の プロンプトに現在時刻が入っていると、出力結果をコピーするだけで時刻も記載されるため便利です。また、iTerm2 等 の Terminal Scrollback Buffer を 大きな数字にしておくと、スクロールすれば履歴を追えるため便利です。
社内と顧客への共有
障害対応に集中するあまり、社内やユーザーへの共有が疎かになることがあります。
障害対応中は、常にユーザーへの悪影響が発生します。何が起きているかわからない状況ではストレスは強くなります。障害が続くようであればユーザー向けの告知を検討しましょう。
このとき、社内のサポートチームへ告知をお願いできると、技術的な障害対応に専念できます。エンジニア以外でも告知を掲載できるツールを用意しておくと良いです。
社内への共有について、顧客対応に加えて、Google や Facebook 等へ広告を出稿している場合は、広告出稿を止めることで余計な出費を抑えることができます。
たまたま、障害発生 と Google の クローラー の巡回が重なって、一時的に検索順位がさがることもあるかもしれません。エンジニアが想定していない影響がある場合もあります。社内共有はしっかり行いましょう。
復旧作業
障害の要因がわかり、障害が継続している(しそうな)場合は、復旧作業をすることになります。原因よって対応は異なりますので、ここでは個別ケースでの対応方法は割愛し、注意すべき点について記載します。
復旧作業をする際には、障害によってデータの不整合が発生していないか、または、応急処置によって不整合が新たに発生しないかを必ず確認してください。特に、MySQL 等のDBで、クエリを 中断(Kill) するとき、 Sidekiq/DelayedJob Jobを中断するときは、そのオペレーションによって何が起きるのかを把握してから実行すべきです。
不用意な中断によって、database の破損 や データ不整合などが起きることはよくあります。障害時に焦ってオペレーションしたばかりに、さらに大きな障害を招いた例は、たくさん経験してきました。
障害対応時のオペレーションは、普段よりもミスしやすいです。まずは落ち着いて、誰かに目視で確認してもらったり、できる限り実行前にバックアップを取るようにしてください。
障害収束後にすること
顧客向け障害報告の掲載
ユーザーからのお問い合わせへの返信、サイトへの告知の掲載など、お客様に対して障害の報告とお詫びを掲載します。どれくらい詳細に記載するかは、障害の範囲、時間、影響など多くの要素が絡みます。ユーザー向けサポートを担当している部門と連携して文案を作成して掲載しましょう。
この際、過去の掲載内容が履歴として残っているとスムーズです。
社内向け障害報告の提出
障害から時間が経つと記憶も曖昧になるし、危機感も薄れます。障害報告は、当日か遅くても翌日には提出するようにしましょう。
社内の過去の障害報告を雛形にして記載すると良いです。可能ならドキュメントツールのテンプレートにしておきましょう。
障害報告を記載する際は、誰に対して報告するのかを明確にしましょう。誰に報告するかで、影響範囲や原因などの説明内容が変わります。以前勤めていた会社で、エンジニアしかわからない専門用語ばかりの障害報告を全社向けにメールして、叱られたこともありました。
スタメンの障害報告フォーマットは下記です。
スタメンでは、障害発生時から対応完了まで 社内のチャット で状況を随時共有しながら障害対応をしているため、障害報告は、エンジニアチーム内での履歴として作成しており、社内向けには「概要」に記載する程度にしています。
## 報告
[年月日] [報告者] (誰がいつ報告したか)
## 概要
(発生した障害についての概要。エンジニア以外にもわかりやすく簡潔に)
## 対応履歴
(障害発生、検知、対応、収束までの履歴を時系列に箇条書きで)
## 顧客対応
(顧客への連絡 や 影響に応じた対応など)
## 発生原因
(障害が発生した原因について)
## 再発防止
(再発防止策とタスクリスト)
## 関連コミット
(障害対応時のコミット、再発防止策のコミットへのリンク)
## 参考資料
(障害対応や再発防止実施時に参考にしたドキュメント等へのリンク)
障害報告で重要なのは、再発防止 です。
障害の原因となったことへの対策はもちろんですが、間接的な要因となった事象についても再発防止を行うこと大切です。
直接的な原因への対策
不具合の理由となったコードを修正する、 アクセス障害の原因となったサーバーを入れ替えるなど、発生原因に対しての対応です。
間接的な原因への対策
不具合であれば、なぜテストで検知・予防できなかったのか。過負荷によるシステムダウンであれば、設計上の課題や、ステージング環境での検証で事前に把握できなかったのか? など。
また、再発防止策として悪い例としては、下記があります。
- 気をつけます。
- ダブルチェックします。
- マニュアルに記載します。
エンジニアは、コードによって、再現性、確実性のある再発防止策を実施できるのが強みです。
気をつけます という気持ちも大事ですし、ダブルチェック もときには必要ですが、どちらも再現性も、確実性はありませんし、マニュアルについては読まれるとは限りません (たいてい忘れ去られる)。
事前の準備
障害は突然やってきますし、素早い判断や対応を求められるため、事前に準備(備え)ておくことが大切です。
- システム構成の把握
- 今からホワイトボードにシステム構成図をかけますか?
- ログの場所は把握していますか?
- CloudWatch 等での監視
- 異常を検知できるような仕組みになっていますか?
- 異常が起きる前の状態も監視していますか?
- データのバックアップ
- 大切なデータが失われないように定期的にバックアップが取得されていますか?
- DB はもちろん、画像など失われるデータはないでしょうか?
- コマンドラインに慣れておく
- mysql
- ps, top, tail, grep などの代表的なコマンドとそのオプションを把握しておく。
- 連絡先の把握
- 休日や夜間に、助けを求められるように連絡先をしっていますか?
- Slack や LINE だと夜間通知が抑制されるときがあるため、電話できると良いです。
まとめ
はじめから障害対応できる人はいません。みなさん、小さな経験を積み上げて、スキルアップしていくものです。ですので、障害に遭遇したらいい経験が詰めるチャンスだと思って、飛び込んでみてください。
先輩がテキパキ障害対応しているときに、飛び込む勇気がないときがあるかもしれません。そのときは「できることないですか?」と聞いても良いでしょう。
過去に、集中して対応しているときに社内調整や告知掲載を引き受けてくれて助かったこともありますし、ランチ前に障害が起きて対応しているときにおにぎりの差し入れをもらって一息つけたこともありました。
私が新人だったころ、障害対応後に喫煙ルームにいって一服している上司を追いかけて、何を考えながら対応していたのか質問していました。また、上司の shell の history を見て、トラブルシューティング方法を学んでいました。
今晩、一人アラートに気づくかもしれません。そのときに、何かしらの対応ができるように今日から準備していきましょう。