すぐに解決できない障害が起きた時にやること

次は、すぐには解決できない障害が起きたときにやることについてです。また物騒な話なんですけど。

例えば、リリースしたら「なんか起きたね」ってなって前のバージョンに戻しました。

でも、データは結局変わっちゃっていて、戻したところでバグっている状態が戻らないということがありました。ロールバックしました。戻らない! わー!? ってなってから2時間くらい戦うということがありました。

あとは、いきなりアクセス急増して、それを想定してなかったパターン。インフラが耐えられる状態になってないときもあるので、そういうところで爆発しちゃって、はてさてどうするか? みたいな感じになったりとか。

最初に個人でアプリケーションを作ったときにそれがテレビに出てしまって、ドッカーンってアクセスが来てサーバーが落ちて、はてさてどうしようか? という気持ちになったこともあります。

あとは、大きめのサービスあるあるなんですが、積み重ねで増えていったチリツモのデータがある日閾値を超えた瞬間にバグの原因になるということがありました。そういったケースはすぐに直しづらいというか、原因がそのときに発生したわけではないので特定しづらかったりします。

すぐに直せないような障害が起きたときは、とりあえず仲間を呼びましょう。「誰かー!」って。かつてあったのは、土曜日の朝7時くらいに電話がかかって来て、「検索できないんだけど!」って言われて。エンジニアが誰も起きてなかったから「とりあえずみんなに鬼電してください!」って言いながら障害対応したことがあります。

何事も、全体として被害が最小限にする考えて動いたほうがよいです。サービスの目線で言うと、全体としてサービスがいい方向にいくには何をしたらいいかって考えて動きますが、障害対応のときは被害が最小限になるにはどうすればよいかを考えて動くのがいいなと思ってます。

バグらせてしまったり障害を起こしてしまったらかっこ悪いからあまり言いたくないんですが、とりあえず報告すべき人にすぐに連絡したほうがいいです。前職ではお知らせを出すのが遅れるとお問い合わせが爆発して二重苦になってしまったこともあったので、報告対象者への連絡はすぐにやったほうがいいです。

あとは、障害対応しながら連絡するのは実質無理なので、「こういうふうにお知らせしてください」って言う係を1人置かないと、集中して調査しながら連絡するのは絶対に無理です。そういう役割分担をするのが大切です。

障害対応を減らすには

とはいえあんまり障害対応は頻繁にやりたくない話なので、どうしたらいいかという話をざっくりお話します。文脈としては、Railsアプリケーションの作成時のお話です。

コードレビューなんですが、細かい文法というよりif文の条件が逆みたいなことがめっちゃあるんですよ。OSSでめっちゃコミットしてる人のコードレビューしたときに、「これ分岐逆じゃないですか?」って言ったことが3回くらいありました(笑)。

あと、救いようがないのがテストコードも実は逆になっている場合。テストコードまで逆になってたら気づかないじゃないですか。テストコードが間違ってるとテストがあってもバグるんですよね。なので、細かい書き方が合ってるかというよりも、そもそもの条件や、やりたいことが本当に実装されているのかを軽く見たり。

意図せず変更がほかの部分に影響を与えるような実装になっていたりするようなこともあります。すごく頻繁にリファクタリングされていてきれいな状態のソースコードであれば起きづらいかもしれませんが、『ハウルの動く城』のように増築されまくっている場合は、「ここをいじると実はここに影響が出て」みたいなことが起きたりします。

なので、ドメインロジックに詳しい人がレビューすると吉ですし、最終的にそういうのはなくしていけるといいですね。

これはややデータベース寄りの話ですが、Active Recordで発行されるSQLのクエリを意識したほうがいいです。心配なところは発行クエリを見て、「これ本番に流して大丈夫なんだっけ?」ということを確認する部分もあります。

これはすごく細かい話なんですが、redirect_toとrenderのreturn忘れもバグの原因になっています。1メソッド内で複数回呼ばれてて、「なんかここのエンドポイントたまに500が返ってくるんだけど何!?」ということで見ていたら、3年くらいreturnを付け忘れていたということがありました。

今の会社ではand returnをつけて安全側に倒そうというルールを決めてやっています。

あとはその変更、ロールバックできるか? 片道切符の変更は基本的に危険なので、なにかあったときに戻せる状態を実装時に作れているかを確認したりします。

また、安全に変更する仕組みやパターンのやり方が世の知見としてあります。サーキッドブレーカーパターンだったり、カナリアリリースというのがあります。

サーキッドブレーカーパターンというのはエラーレートが何パーセント以上であればこのエンドポイントへのアクセスをやめる、みたいなことを自動でできるように実装しておきます。

なにか起きたらブレーカーを落としたり戻したりするようなコードを書いておくと、例えば深夜にすごくアクセスが来てエラーが出たときだけオフにするから、夜中にアラートで叩き起こされずに済みます。

あとはカナリアリリースといって、新機能を一部のユーザーのみが使える状態にして段階的にリリースするという仕組みがあります。例えば、社内のユーザーだけ新機能を乗せるサーバーを作っておいて、そこで確認して大丈夫そうであれば全ユーザーのサーバーに反映する。これも怖い系の新機能を作るときには便利だったりします。

あと障害対応レポートってあまり書きたくない風潮がありますが、なにか発生したら知見の蓄積としてやったほうがいいなと思っています。それを読み合わせる人、再発防止策を考える人は、(障害を)起こした人やその周辺のチームの人だけじゃなくてもっと広い範囲の人でやったほうがいいなと思っています。

あと「気をつける」というのが再発防止策に出てきがちなんですが、気をつけなくていい仕組みを作っていく方向に再発防止策を持っていったほうがいいと思います。なんだかパラドックス感がありますね。

まとめです。

障害対応から学ぶことはたくさんあります。怖がらずに落ち着いて参加しましょう。また、ベテランの人は積み重ねを伝授するような動きをやりましょうという話です。

全体として被害を最小限にするということを考えてやると平和な世界になります。あとは日々の仕組みづくりで不必要な障害対応を減らすと平和な生活ができます。以上です。ありがとうございました。

(会場拍手)

過去に最も印象的だった障害

司会者:どうもありがとうございました。すごく実践的な知見が詰まっていて、Twitterとかでもこの資料をぜひ公開してほしいという声があるんですけど大丈夫ですか?

しなもん:大丈夫です。

司会者:よかったです。では、質問タイムですね。なにかしなもんさんに聞いてみたいことがある方、挙手お願いします。

(会場挙手)

質問者1:これまでで一番劇的に印象的だった障害や、一番倒すのが難しかった障害のどちらか。両方でも。お願いします。

しなもん:データベースのレプリケーション遅延でデータがずれまくって……というのが強烈でした。

倒せなかったものはElasticsearchのサーバーの設定が悪くて、サーバーを全部建て直しました。2、3日置いてるとまたサーバーにアクセスできなくなって、そこからまた違うサーバーを立て直して、みたいなことを3回か4回くらい繰り返してチューニングしたことがありました。「またお前か!」みたいな感じでした。

ちょっと詳細はお話しできないのであとでしゃべります(笑)。

質問者1:ありがとうございます。

深夜メンテナンスに憧れを持った理由

司会者:ほかありますか?

(会場挙手)

質問者2:とても興味深くおもしろいお話をありがとうございました。先ほど過去に書いたブログの一部を見せていただいて、深夜メンテナンスに謎な憧れがあったということだったんですけれども。憧れを抱くに至った経緯は何なのかちょっと知りたいなと思いまして。

(会場笑)

普通、深夜メンテナンスのメンバーを募集してもみんな嫌な顔をするということが多いので(笑)。どういう経緯でそこに憧れを抱くに至ったのかを教えていただければと思います。

しなもん:変な奴だとよく言われるんですけど。新卒のときに20人くらいの部署で、「深夜メンテナンスやります」ってなったときに強い人ばかり選ばれてたんですよ。

だからこれに選ばれるということは強いということなんだと思って。そういう意味で憧れていました。「強い人がすごいことやってるから私もやってみたい!」みたいな感じでした(笑)。

メモをどうするか

質問者3:すごく実践的で素敵な発表でした。ありがとうございます。障害対応のメモを取っているとおっしゃっていましたが、会社のメモ的なところじゃなくて個人のほうで取ってるようなかたちですかね?

しなもん:メモは会社で振り返りをするときに書いたり、スクショを貼ったりする感じですね。個人というより会社用のQiitaやKibelaに書いちゃう感じです。

質問者3:なるほど。私も今そんな感じのことをやってるんですけど、何年後かにその会社からいなくなったときに、全部アカウントが見れなくなってしまうので、ほかの人はどうしているのか気になっていたんですけど。意外と自分の中で蓄積されるものですか?

しなもん:外に出したいなと思ったら、社外公開向けのブログの形式にしちゃえばいいなと思っています。でも、何回かやっていたらわりと覚えてたり、だいたいこうだろう、みたいなのがあったりします。

おそらく会社やサービスによってだいぶ傾向も違うので、けっこうケースバイケースですね。根底にあるものは何回もやってるうちに覚えるので、そこまでメモしなくてもいけたりします。

質問者3:ありがとうございます。勉強になります。

司会者:ありがとうございました。しなもんさんに大きな拍手をお願いします。

(会場拍手)