stefafafan の fa は3つです

すてにゃんのブログです

Webアプリケーションの障害対応について改めて意識すべき点ややれると良いことをまとめる

Webアプリケーションエンジニアをやっていると時たま障害が発生し復旧作業にあたるのだが、人によって「障害対応が得意」だったり「苦手」だったりする。ただ、障害対応時の「良い動き」というのが実際どういうものなのかというのが自分の中でふんわりしていたので、ざっくりはてブで「障害対応」で検索していくつかのエントリーを読んでみたり、自分の仕事での経験を振り返ってみたりして考えたことをまとめてみた。

障害にはフェーズがある

障害対応したことないと、障害には「障害中」「障害中でない」の二つの状態しかないと思うかもしれないが、実はフェーズがいくつかあるというのを理解しておくのが大事。最近以下のエントリがとても参考になった。

Webサービスの障害を人間の病気と同様にあてはめてみると、急性期、回復期、慢性期に当てはめられます。また、病気の期間について調べたところ前兆期という言葉も見つけたのでこれも使ってみます。

Webサービスの障害対応のときの思考過程 - ぱいぱいにっき

上記のエントリでのフェーズの分け方がとても良いなと思っている。この中でも特に「障害が隠されているが根本的に対応されていない」状態と「根本対応も完了している」状態が別れているのが良い。

他の方のエントリにもあるのだが、障害が発生しているときは1ステップで根本解決完了まで行く必要は実はなくて(というか原因がすぐにはわからないことも多々ある)、一次対応が最初のゴールというのを意識できると良い。

障害対応には複数の役割がある

障害が発生しているので、まずなんとしても一次対応をせねば!と思い、エンジニアみんなで原因を調べたり直そうとしたりするのは効率的ではない。複数人で対応可能なら、連携がどうしても大事になってくる。障害対応時のロールとしては、「指揮官・司令塔」「調査・復旧係」「書記」の少なくとも3つのロールが一般的らしい。

  • インシデント指揮官 (IC = Incident Commander) - あなたです!
  • 主任SME (SME = Subject Matter Expert) - 問題に対し技術的な調査を行う
  • 外部通信役 (External Liaison) - インシデントに関する顧客との連絡を司る
  • 書記官 (Scribe) - Slackにインシデントに関するノートを書き、フォローアップが必要な項目を追い続ける
インシデント指揮官トレーニングの手引き | Yakst

役割を担える人数として最低3名は必要だと考えています
1. 司令塔(外部通信役)
2. 原因調査・復旧
3. 現在の状況観測(記録役)

今日からできる。初めての障害対応ガイド | Developers.IO

障害発生したタイミングでまずは人を集めて、ロールを決める。その後フェーズごとにロールそれぞれの役割に従って作業ができると良さそうだ。

これについては、以下のエントリの「役割別のインシデント対応フロー」という図にて、フェーズごとに各ロールが何をすべきかというのがまとまった表があり、参考になる。
medium.com

また、役割も決めず、人も呼ばずに一人で黙々対応していると精神的にもよくないという意見もある。

一人で、システム障害に立ち向かうと、頭がおかしくなります。

頭がおかしくなると、普段平常時には絶対にやらないようなことを人間はやってしまいます。

システムの障害対応時に心がけること - orangeitems’s diary

ただでさえ障害対応するにはやることが多いのに、それをリスクを負って一人で高いストレスの中やるのは効率の面でも安全性の面でもできることなら控えたほうが良いだろう。

障害対応をスムーズに進めるための目的は複数ある

やることが多いし一人だと大変だから複数人で並行して進めると良いという話をしたが、一体何のためにスムーズに対応をしたいのかというのが抜けていた。以下の観点で障害対応の特に一次対応はスムーズに進めたい。

  • ユーザ影響のある障害の場合は特にユーザからの信頼を失うリスクがある
  • サービスを正常に提供できていないとなると、ビジネス面でのインパクトがあり、状況が長く続けば続くほどインパクトが大きい
  • 書記がしっかり状況をまとめたり、振り返りを行うことにより、このパターンの障害の二回目以降のリスクを大幅に下げることができるようになる

ユーザに対して正しくサービスを提供できないサービスはサービスを提供しないことよりも悪いという考え方のもとに立っています
……
とはいえ、機能を止めたりメンテ入りさせたりするのは、ビジネス上のインパクトが激しく、サービスのステークホルダーの判断が必要です。

Webサービスの障害対応のときの思考過程 - ぱいぱいにっき

障害対応の難しいところの一つは、ただ原因や対応を考えて実行して終わりではなく、そもそもその対応を行ってしまって良いのかどうかや、お客さんにどう報告するのかとかを考える点もあるということ。そのためステークホルダーとは必ず会話するロールが必要であり、書記や原因調査・対応を行ってるメンバーとは別のメンバーであるのが望ましい。

障害の影響度=影響範囲 * 金銭的重要性 * 対応完了までにかかった時間

エンジニアなら知っておきたい障害報告&再発防止策の考え方 - Qiita

上記の式が個人的に結構わかりやすくてよかった。ステークホルダーとしては、影響範囲と対応完了見込みは知りたいだろう(影響範囲がわかれば、金銭的重要性はステークホルダーであればわかるはず)。

スキルも必要なので練習していけると良い

障害対応する際に「指揮官」も「書記」も「原因調査・復旧」もそれぞれやることはわかっていても、誰でも簡単に上手くやれることではなく実はちゃんとスキルが必要。

例えば以下のエントリのインシデント指揮官のやることで、主任のエンジニアとのコミュニケーションについて書いてあるが、こういう効率的なコミュニケーションは練習なしではなかなかうまくやれないと思う。

もし主題のブレに気づいたら、主任SMEに対して、どのような考えから各々のアクションを取っているのかを聞くのを始めてみると良いでしょう。 たとえば「データーベースのエラーログを調べている」と言われたら、「データベースにエラーがありそうだという考えに至った理由は何かな?」といった返しをしてみます。 調査の中、どのようにしてデータベースの課題から問題が引き起こされうるのかや、なぜデータベースのエラーログによって根本原因を突き止められそうなのかをを説明するよう、主任SMEたちをかき立ててみましょう
……
「もし、この変更が問題の原因ではないことを証明するとしたら、どうやって証明する?」 このように概念的な見方の転換を行うことで、必然的に調査者は狭いトンネルの外のアイデアに目を向けることとなり、しばしば前進を再開することにつながります

インシデント指揮官トレーニングの手引き | Yakst

「原因調査・復旧」係の場合も、普段の開発と比べて時間的制約が厳しい一次対応時の判断も最初は難しいはず。障害が発生したら効率よく問題の切り分けができる必要がある。

スコープを狭めるというのは、例えば、ECサイトの価格表示がおかしいとします。表示部分が一番事象そのものなので、まず発生している条件が全商品なのかどうかを確認します。そして、特定の商品やカテゴリにのみ発生していると分かったら、価格が格納されているデータベースを確認します。正常値が記録されている場合、データベースからViewにわたる経路がおかしいと辺りが付けられます。こうすることで、見るべき範囲(スコープ)が狭まってきます。
……
大きく分断するためには、要素ごとのインターフェイスを調べます。DBとWebAPIならDBの値でしょうし、WebAPIとViewであればWebAPIのJSONフォーマットの値でしょう。
どこの要素から分断するかについては、すぐ確認できるものからという、ラフな選び方でいいと思います。もしくは、心当たりのあるもの。二分探索的に見ると、真ん中から切り分けるとかでも良いのかもしれないです。確認ステップが、もしかしたら減るかも。

システム障害と僕達はいかにして戦えば良いのか、障害対応について考えた - Qiita

こういう障害対応時に「良い動き」ができるようになるには経験がほしいところだけど、障害はそんなしょっちゅう起こるわけでもない。そういう時のために障害対応の避難訓練を行う会社もわりとある。

ベテランメンバーが不在のときにシステム障害と向き合えるか不安に思うという声が上がりました
……
この不安を解消するため、システム障害発生時にスムーズな役割分担や動き (検知・情報共有・復旧) ができるようになることを目的に「障害対応演習」を実施しました。
……
メンバーはみな技術者ですので、役割分担するつもりでいても、つい手を動かしてしまい、作業とコミュニケーションの両立に苦しんだようです

システム障害対応演習を実施した話|NAVITIME_Tech|note

上記のエントリでもやはり役割分担やコミュニケーション周りで苦戦していたようなのでこの辺りの役割を明文化したり練習していけると良さそう。

初心者でもやれることはある

自分もそうだが最初のうちはシステムをよく理解していなくてスキルも低い自分がやれることはなかなかないと思ってしまっていたが、実はやれることとても多いので、その中でもどれか選んでやれると良さそう。個人的には「書記」からやると良いのではと思う。以下のエントリにもいくつか案が載ってました。先輩とペアオペ・ペアプロするのも良い。

オススメはissueを作る、以外にもタスクがあります。
1. 書記として実況してまとめる
2. 関連部署(例えば営業やマーケ)に定期報告する係
3. チャンネルを作る
4. 障害対応者や調査者のペアオペ

障害対応時にまずはissueを作ると良い - そーだいなるらくがき帳

以下のスライドの「先輩より早く原因特定するゲームを実施する」というのがちょっと面白かった。障害対応のときに明確なロールを持っていないけど手が空いてて見てる、みたいな時は自分でもコードを眺めたり最近のリリース内容を見て「原因特定するゲーム」してみるのは面白そうかもしれない。ただしロールを持っていない人が横から口出しすると「良い動き」とは言えないので気を付ける必要がありそうだ。

先輩より早く原因特定するゲームを実施する

システム障害との向き合い方 @sinamon129 #tokyogirlsrb - Speaker Deck

同じスライドで良い話だなと思ったのは、障害対応の経験で、コードレビューでどこを見ればいいのかがわかってくるという点。仕事でコードを書くときに「テストを書こう」という話を聞くことがあっても、テストのありがたみを感じることがあまりなかったりするので、実際に障害の対応としてテストが追加されるのを目の当たりにすると良いのかもしれない。

コードレビューでどこを見ればいいのかが分かってくる

システム障害との向き合い方 @sinamon129 #tokyogirlsrb - Speaker Deck

実際やってみると良さそうなこと

いろいろ書いたのだけど結局なにをやると良いのかというのをまとめると、

  • 障害対応時にやることをテンプレート化する
  • スムーズに対応に入れる仕組みを整える
  • 障害対応避難訓練

の3つで落ち着くと思う。

障害対応時にやることをテンプレート化する

障害対応にもスキルは必要と書いたものの、ある程度流れは決まっているのでテンプレートは作ったほうが良い。弊社では最近Scrapboxに「障害対応テンプレート」のページを作っておいて、障害が発生したらそのページを複製して対応しているが、人によってはGitHubのissue templateを使う人もいるのもインターネットで観測してる。

  • 「役割を決める」段階があること
  • 障害のフェーズを意識していて、簡潔になっていること

が大事だと思っています。役割が決まっていないまま障害の対応をすると効率よく進められないし、テンプレートが長いと障害対応そのものが大変になってしまう。

役割ごとに「一次対応」でやること、「根本対応」でやること、「収束後」でやること、などを全て書いていても結局障害発生直後は一次対応でまず何をやるかが知りたいので、わかりやすくセクションわけておけると良さそう。

スムーズに対応に入れる仕組みを整える

これは障害が発生したときにテンプレートまで辿り着けずになんとなく対応してしまうのを防ぐためにやりたいことです。例を書いてみる。

  • Slack botにテンプレート用のリンクを吐かせる
    • もっとがんばりたければ、テンプレートの手順を順番に言ってくれるbotを作るのも良さそう
  • 障害対応会場や手順を予め決めておく
    • 障害用のSlackチャンネルを毎度作って振り返りまで終えたらチャンネルを破棄する
    • コロナ禍の間は障害が発生したらまず全員Google Hangoutやzoomつなぐようにする
障害対応避難訓練

実際に作った障害対応のテンプレートやフローを使って、擬似的な障害対応で実践する練習はできると良さそう。

特に、経験が浅いメンバーがテンプレートを使ってスムーズに対応できるかどうかをチェックするというのがテンプレートの項目チェックの意味でも経験をつけるという点でも二重でメリットがあると思う。

一方で、トレーニーから復旧手順についてフィードバックをもらい、チームとして実施すべきアクションを洗い出しました。定型化された手順に対する感覚はベテランほど鈍くなってきますので、経験が少ないメンバーから新鮮なフィードバックを得る貴重な機会となりました。

システム障害対応演習を実施した話|NAVITIME_Tech|note

おわり

いろいろなエントリを読んで、同じようなことを書いただけのようにもなったような気もするが、個人的にも書いてるうちに弊チームの障害対応フローも一部改善できそうというのが思いついたのでまとめてよかったとは思う。避難訓練も自分は経験少ないのでやってみたいと思った。