バグ対応で疲弊しないためにやってること
バグは無くならないのか?
先日、開発者の時間の使い方について調査した記事を読みました。
Stripe社とHarris Pollの調査(On average 41% of developers time is spent on technical debt)によると、開発者は平均で作業時間の41%を技術的負債とメンテナンス作業に費やしており、そのうち週に3.8時間はバグのある「悪いコード」のデバッグに費やされているそうです。 この「悪いコード」による機会費用は年間850億ドルに達するとのことでした。
悲しくも難しい現実ですが、実際のところエンジニアとしては向き合う必要がある課題だなと・・。
とはいえバグを0にすることはできないと思っていて、バグを0件にする = 開発をしないことになると思います。
開発をしなくていい、そんな完全体なプロダクトは基本的にはないと思っているなかで、影響を最小限に食い止めて、デジャヴを感じるバグは無くしていきたいという強い意志は持っています。
バグ対応の流れ
バグが起きるとすごく焦ります。焦ると思考が浅くなって、誤ったプログラムやデータの修正を行ってしまうリスクが高まります(もちろん経験あります泣)。
なので毎回焦らなくていいように6つのステップにしました。
火を消して広がらないようにする | 暫定対応
いわゆる暫定対応です。
家事が起きたとします。救急車が駆けつけて、負傷者を救護し、他のひとを入れないようにする。これが暫定対応です。とにかくいまこの瞬間の被害を全速力で最小限にするのが暫定対応です。
システムで言えば、該当機能を一時的に止める・リバートするとか、不具合が起きたデータを手動で修正するとかになることが多いです。
大概はそのシステムに詳しいひとを連れてきて見てもらうのが一番速いので、1人だけで頑張ろうとしないことも大事です。社会人1限目、「報連相」に立ち返って迅速にステークホルダーに報告して対応します。
火の出元を調べる | 原因の調査
暫定対応で火が消えたら、次は「なぜ火事が起きたのか」を調べます。
システムで言うと、ログを見たり、再現手順を確認したり、コードを追ったりでしょうか。
焦って、たぶんこれが原因だろうで進むと、後でほぼ確実に再発するので、本当の原因を調べきります。
飛び火の対応 | 影響範囲の調査と対応
以下のような視点で考えてみます。
- このバグ、他のユーザーにも影響してないか?
- 同じパターンで別の場所でも起きてないか?
原因が分かっている = 発生する条件が分かっているということなので、SQLを書く等して他のユーザーの影響範囲を抽出し、バグの影響を受けないようにします。
根本から直す | 恒久対応
原因が分かったら恒久対応です。
火事の例でいうと、調査の結果、古い配線がショートして火が出たことが判明した。だから配線を新しいものに交換して、漏電ブレーカーも設置する。
システムでいうと、該当機能を改めて動かしてもバグが起きない状態にするためにプログラムを修正することになることが多いです。修正して改めて再リリースを行います。
恒久対応に時間がかかる場合 | 暫定対応の仕組化
恒久対応は時間がかかる場合があります。コードの修正、テスト、レビュー、リリースという開発フローを通すのは一定時間がかかるものです。修正の影響範囲が大きい場合は尚更で、時間がかかるのは仕方ないですし、むしろ時間をかける方がいいです。
とはいえそれまでバグの影響が出続けるのは避けたいので、恒久対応が終わるまでのつなぎとして、暫定対応を何度でも実施できる仕組みを作っておくことが大事です。
例えば、
- データの不整合が起きたら自動で通知させる
- 特定のエラーパターンを検知したら通知させる
- 手動対応の手順をドキュメント化
次もし同じ問題が発生しても(発生しそうになっても)、すぐに気付ける・誰でも対応できる状態にしておきます。
仕組みや文化を作る | 再発防止
再発防止の目的は、今回火事が起きた場所だけじゃなく、他の場所でも同じような火事が起こらないようにすることです。
まず仕組みとして、定期的な電気設備の点検を導入したり、火災報知器を増設したりができそうです。
そして文化として、住民向けに火災予防の講習会を開いたり、火の元チェックリストを共有したり。一人ひとりが火事を起こさない意識を持つ環境を作っていくのも大事だと思います。
開発で言えば、仕組みはテストの自動化を進めるとか、監視を強化するとか。文化はコードレビューの基準を明確にするとか、定期的にポストモーテムをやるとか。
ヒトではなくコトに向き合って、チーム全体でそもそも問題が起きにくい環境を作っていくことが再発防止になると考えています。
大企業の事例から学ぶ
AWSが2021年に大規模障害を起こしたときは、影響のあるリージョンをすぐ切り離して(暫定)、負荷分散の仕組みを強化して(恒久)、監視とアラートを改善した(再発防止)っていう流れでした。
Facebookも同じ年にDNS設定ミスで全世界ダウンしたときは、ネットワークを復旧させて(暫定)、DNS管理プロセスを見直して(恒久)、設定前の自動テストを強化しています(再発防止)。
チームで共通認識を持つこと
バグやインシデントが起きたとき、感情や勢いで動くんじゃなくて、型に沿って対応できると、判断がシンプルになり対応漏れが減ります。
同時にこれがチーム全体で共通認識として持てているかも重要です。一人だけが知っている状態はリスクが高いので、このステップが当たり前になってると、かなりスムーズに動けます。
僕もまだまだ完璧にできているわけじゃないですし、プロダクト改善もできることが残っていますが、この考え方を意識してから、少なくともプロダクトを強くさせられている自信は付いたのと、焦らず凹まずに対応できるようになりました。
ぜひ皆さんのチームの仕組みも教えていただけたら幸いです!
Discussion