システム障害との向き合い方

しなもん(@sinamon129)氏(以下、しなもん):お願いします。素敵なキラッとした話のあとにシステム障害の話をします。よろしくお願いします。

しなもんといいます。

今はWebメディアとECをやっているRiLiという会社で取締役CTOをやっています。RailsGirlsのコーチをやったりとかしています。アカウントは@sinamon129でやってるので、たいしたことはつぶやいてないですがフォローしてください。

今回なんでこんな話をするのかと言うと、そこに座っているりさきゃんちゃんから「ごりごりテックな話をしてくれ」と言われて。そんなにテックな発表はとくにやったことがなく、これまでのエンジニア人生で自分の中で大きかったと思うのは障害対応と深夜メンテだと思ったので、この話を持ってきました。

前提の文脈として、私は社会人になってからはC向けのプロダクトしかやったことなくて、大きさはだいたいスタートアップにいることが多かったので、MAXで20人くらいの開発現場です。なので仕様設計、開発、テスト、リリース、運用まですべてやるみたいな状態でした。

Webアプリケーション開発なので、だいたいの場合はRubyとRailsです。クラウドインフラからバックエンドまでなので、例えばAWSやGCPでインフラを立てて、Railsを使ってWebアプリケーションを作るといった感じの文脈でお話しします。

おそらく会社によって雰囲気が違ったりすると思うので、あくまでそういう感じだと思ってください。

システム障害対応とは

まずアンケートなんですが、障害対応をやったことがある人?

(会場挙手)

おぉ、けっこういる! ありがとうございます。

どんな種類のシステム障害があるかなと考えたんですが、私がやらかした一番血の気が引いたやつは、実装時にミスって、当時検索エンジンというか検索サーバーのお守りをやっていたんですが、検索用のデータを全部吹っ飛ばしたことがあって。その日にちょうどテレビに出るからって言われてて、けっこう血の気が引きました。復旧できたからよかったけど。

あとは手動操作のミスですね。コマンドを打ち間違えちゃったとか、変なデータをアップロードしちゃったとか。あとはテレビとかアクセスがめちゃくちゃ来て見れなくなったとか。他には使ってるサービスの不具合で、極端な例で言うとデータセンターが火事になったとか。

(会場笑)

あ、データセンターが火事になったことはないです!

これらの1個、もしくは複合でシステム障害が起きるかなと思っています。自分たちが提供しているサービスが「期待しない状態」になっているときに対応する、という話ですね。

障害が起きてから収束するまでの間にいつも何をやるかと言うと、発生して、それに気づく。発生したときにすぐ気づける場合もあるし、ユーザーさんから「見れないんですけど」と言われて初めて気づいたりするときもあります。

それがわかったら、まずは調査をして原因を突き止めて、とりあえず当たり障りのない感じに戻すという一時対応をやります。そのあと収束したら、振り返りをします。例えば雨漏りしたときはとりあえずバケツを置いて一時対応して、そのあとに雨漏りの根本を直すということですね。

さっきもいいましたが、エンジニア人生において障害対応で学んだことがめちゃくちゃ多いので、私が新卒1年目のときから今まで、どのように障害対応と触れ合ってきたかという話をします。障害対応は怖くないですよ。あくまで私の経験なので、「こうしろ」みたいな話ではないです。

あと、今私はスタートアップにいるので、同じようにスタートアップで1人でエンジニアでをやっていて、障害対応をやらざるを得なくてくてやってきたんだけど、そのあとにメンバーが増えて、だけど自分以外障害対応できなくて困ってるんだよね、という相談にのることがすごく多いので、このへんの話にも触れられたらなと思います。いろんなスキル感の人に参考になればなと思っています。

障害対応はすごい人がやると思っていた

社会人1年目のとき、障害対応と深夜対応はすごい人がやるものだと思っていました。10年物のサービスの部署にいて、20人くらいエンジニアがいたんですが、今まで見てきたコードベースというか、コードのかたまりと比べると規模がめちゃくちゃ大きくて、ぜんぜん把握できる大きさではありませんでした。

けっこう前なのでエラーが起きるとメールでエラーログの破片が飛んでくるんですが、「これを見たところでどうしたらいいんだ!?」みたいな感じになっていました。とりあえず自分がどうもバグを仕込んだらしいという指摘が入ったときだけなにかやるけれど、それ以外のときは何もできませんでした。

そのため、ベテランの人たちは対応しててすごいなと思っていました。興味あるけど自分の仕事で精一杯なのでとくに突っ込んでやるというわけではなく、「どうやってるんだろうな?」と思ってました。

初心者期

私は社会人2年目で転職をしました。

転職した先はもうちょっと小さいベンチャーで、当時はWebアプリケーションエンジニアがだいたい6人くらいの環境でした。私が一番経験が浅い状態で、とりあえず新規サービスがやりたいから早く独り立ちしてくれ、みたいな状況でした。

私も1人でアサインされて、私がエンジニアとして1人いれば成立する状態になるといいなと思っていたので、できないことを減らそうと考えていました。Webアプリケーションもそうだし、インフラもそうだし、できないことを減らそうと思って奮闘していました。

いろいろ実装して本番にあげると障害が発生してしまうこともけっこうあるんですね。最初は障害が発生すると「どうしよ、どうしよ、どうしよ!」ってすごく焦っていたんですが、先輩に「焦りすぎだからとりあえず落ち着け」って言われて。確かになってなりました。

いつも柔らかい口調でしゃべる先輩から「焦りすぎだから落ち着いて!」と強めに言われたからちょっとびっくりしたという(笑)。落ち着いて見えるようにしていると、そのうち「あ、また起きたな~」みたいな気持ちになります。

あと、よくわからなくても障害対応には参加したほうがいいです。会社でやっているとアラートが来たり、不具合かもしれないです、という報告を受けたりします。そんなとき、先輩たちは「これは〇〇が原因かもですね」みたいなことを話し合っていました。

そこに一緒に参加して、例えば「DBのCPUが上がってるから、もしかしたらさっきデプロイしたあれが原因かもしれないですね」みたいな話をしていたので「それは何を見てその話をしているんですか?」みたいなことを教えてもらいながら、問題の切り分け方を実地で学んだことは良かったと思います。

あとはとりあえずバケツを雨漏りに対してサッと差し出すことに関してはなるべく早いほうがいいので、教えてもらったりすると復旧に時間がかかってしまうので、対応が終わったあとに振り返りをして、根本的にこういうところを変えないといけないよね、みたいな話に一緒に入って、問題に近いところを理解できると理解が深まってよかったです。

あとはこれは勝手にやっていたんですけど、先輩より早く原因を特定するゲームを脳内実施していました。

(会場笑)

まず、先輩方より早く問題発生に気づいて一番最初に原因を探し始めます。コードやインフラのメトリクスみたいなところ、グラフのところとかは経験値が効いてくるんですけど。

今日何をリリースしたかであったり、先ほどこれを変更した、というのは経験ではなく見ていればわかる話なので、そこをチェックしておいて「これってもしかしてさっきのこれじゃないですか?」というのをやって当てていくというゲームを1人で実施してました。

他には、例えば1年間に2、3回しか変更しない設定だったり、全停止メンテナンスをするなど、今までやったことのないことをやる場合は「どうやるか知らないので横で見ててもいいですか?」と言って見せてもらいながら、最終的に自分が横で見てもらいながら実施できるようにしました。それで増えた知識もたくさんあります。

少し慣れてきた期

なんやかんやでそれを繰り返していると、1年後くらいには障害対応や深夜メンテに参加するのが自然になってきます。

これはそのときの日記というか、振り返りなんですけど「とりあえず最初は存在してるだけであまり戦闘力として機能していなかったが……」って書いてあってちょっとおもしろいですね(笑)。

実際に対応していると、何がまずいのかわかってきます。ただ「胃が痛い」って書いてあります(笑)。

経験を重ねるに連れて、問題の切り分けがだんだんスムーズになってくるんですね。進研ゼミの「これ、あのときに発生した障害だ!」みたいなやつですね。

(会場笑)

解決のために周りのコードを読んだりしているので、問題の切り分けも早くなっていきます。けっこう年数が経っても、障害が起きてなにかした時はインパクトが強くてめっちゃくちゃ覚えてるんですよね。半年前に実装したコードのことより障害が起きたことのほうが覚えてるみたいなことがあります。

障害対応だけじゃなく、発生している問題の原因が自分の中にインプットされるので、例えば実装するときにここは過去にテストを厚めに書いてなかったせいで障害になってしまったことがあるとか、データベースに影響が出そうなコードを書いているかもしれないから、その部分のチェックを強めにしておくなど、実装するうえで見るポイントみたいなのが増えました。

当時、先輩のコードレビューをし始めたんですが、すごく整ったコードがプルリクエストできて。すごくよさそうだったので、これは何を見ればいいのかな? ってずっと思っていたんですが、実際のコードの書き方というよりは、これをリリースしたときに何が起きそうかを見ることが大事なのかなと感じました。

あとは、難易度の高い障害に立ち向かう羽目になっていきます。いろいろなものを直していると、どんどん問題のレベル感が上がっていきます。例えばなにか起きました、直しました、しばらくしたらまた違う傾向で再発して、直して、みたいなことを繰り返す苦しい時期もありました。そのときってしんどいんですが、直すためにいろいろ調べることで知識が増えるので、すごくよかったなと思っています。

仕切り期

そのうちだんだんメンバーが増えてきて古株になってきたりして、障害発生の原因特定や修正は勝手に1人でできるようになっていきました。

逆に新しく入ってきたメンバーもやってくれないと体が保たないような感じになっていったので、とりあえず障害が発生したら叫ぶことにしていて。

(会場笑)

例えばアラートが飛んできたら、とりあえず既読替わりに「お!」って言う文化ができました。「お!」って書いた人は見ているみたいな感じで、この人が見ているということを確認したり。

さらっと調査したうえでこいつはまずいということになったら、「やばい! 今なんか起きてる!」って物理で叫ぶ。すると人がワラワラ集まってきてなにかが始まるので、これはよかったです。

あとはどこを見て何を考えたかを発信する。新しくシステムに触る人ってベテランのエンジニアであってもサービスドメイン的に詳しくないので。「今これを調べてて、これを検索したんですけど」とか「このグラフを見たら……」みたいな。「さっきリリースしてたこの機能は……」みたいな話を説明しながら一緒に対応したり、ペアで画面を見て、「今から横で説明しながらやるので、わからないことがあったら聞いてください」みたいな感じでやったりとか。逆にオペレーションをほかの人にやってもらって、横から指示を出すみたいな感じで障害対応をしていました。

あとはこれが原因だとわかってても、一旦収束していたら時間がかかってもいいから誰かに直してもらうこともありました。

1人で切り盛りしてきました系の人はずっと1人でやりがちなんですが、それをやってしまうと組織として健全ではありません。なので、週替わり・日替わりで担当を作ったのはよかったなと思います。

まとめです。障害対応はすごく学びが多いので、戦力にならなくてもとりあえず参加してみるのが大事だと思っています。自分が対応できなくても学びに変えられるのでとてもよいです。解決力が上がったら、積み重ねたことをみんなに伝播してヘルシーな障害対応ライフを送りましょう。