こんにちは!NewsPicksエンジニアの森川です。今回はNewsPicksのオンコール(=障害対応)体制の変遷と試行錯誤をご紹介したいと思います。
オンコール1.0 ~ 全員野球時代 ~
NewsPicksにはエンジニア全員が入るslackチャンネルがあり、ここで周知事項の共有や雑談、問い合わせがされています。昔はこれに加え不具合の報告や監視システムからのアラート通知もこのチャンネルに流れるようになっており、アラート通知は気づいたエンジニア皆で拾う、言わば全員野球のような形で障害対応がされてきました。 チームやサービスの規模がまだ小さく、メンバーの多くがシステム理解度が高い状態であれば、これで十分、というより変に監視体制の整備や役割分担にコストをかけずスピード重視で動ける、最適な状態だったのではと思います。
2018〜2019年にかけて、事業の拡大に伴いエンジニアが急増しました(私もここで入社しました)。開発体制が強化され、システムが横に拡大しアラートが増える一方で、システムをまだ把握していないメンバーが増え、全員野球での障害対応がワークしなくなってきました。
異変によく気づき、システム理解度の高い一部のメンバーに対応負荷が集中し、また一部のメンバーのみが対応する事でノウハウ共有が進まず、さらに属人性が高まる状態になっていました。
オンコール2.0 ~ 当番制時代 ~
負荷が一部の人に偏り、ノウハウが共有されない問題を解決するために、以下が行われました。
まずslackのエンジニア全員が入っているチャンネルから、アラート通知と障害報告を専用の別チャンネルに切り出しました。
次にオンコール対応を当番制にしました。エンジニア全員を1次受けラインと2次受けラインに振り分けます。2次受けにはシステム理解度の高いシニアエンジニアやリーダーを割り当てます。
記事の公開時刻やアクセス負荷などのNewsPicksのサービス特性に基づき、1日を朝番・昼番・夜番の3つの時間帯に分け、それぞれに1次受けが1人ずつ割り当てられます。1次受けは担当時間中、slackのアラートチャンネルを確認し、通知があれば対応します。対応できない場合は2次受けにエスカレーションします。
この体制により、アラートをエンジニア全員で対応できるようになり負荷は平準化されましたが、同時に改善点も見えて来ました。
1. 専門外のアラートに対応できない
サーバ・ iOS・Android などの職能に関係なくローテーションを組んでいた為、例えばiOSエンジニアがサーバのアラートを受けるなど、専門外のアラートにも対応する必要がありました。多くの場合、原因が分からずエスカレーションするしかない為、1次受けが効果的に機能せず、貢献感も得られない状態になっていました。
2. 対応するエラーの数が多すぎる
エラーやアラートに緊急度の差があまりなく、通知されたもの全てを確認していた為、単純に対応するアラートの数が多く負担が高くなっていました。
3. 勤務時間の自由度が減る
弊社はスーパーフレックスを採用していますが、この体制では当番時間は全て勤務するルールにしていた為、土日含め朝早や深夜に固定時間勤務をしなければならず精神的に辛い状態になっていました。
4. slackに気づけない
上記のように当番中は基本的にPC前にいるものの、開発に集中している時や早朝、移動中にslackを見落とすケースがありました。
全体的に、この時の体制は全てのエラーを全員でカバーしようとしてコストの高い仕組みになっていました。これはSLOの考えにも繋がりますが、必要な可用性のレベルはサービスの性質によって異なります。極端な話、人の命に関わるシステムであれば、多大なコストをかけてでも1つ1つのエラーを監視し対応すべきですが、私たちの提供するサービスがソーシャル経済メディアであることやエンジニアのリソースが有限であることを考えると、オンコール対応レベルを見直し、疲弊しない仕組みに変更した方が良いと考えました。
オンコール3.0 ~ PagerDuty時代 ~
当番制で見えた課題を解決する為、以下の改善を行いました。
1. アラートを緊急度で仕分け
まず監視項目を見直し、「ユーザ視点でクリティカルか」でアラートの緊急度を分けるようにしました。NewsPicksでは主にCloudWatch Alarmでインフラ、Bugsnagでアプリケーションエラーの通知を行っていますが、緊急度の見直しによりCloudWatch Alarmでオンコール対応が必要なものは約700種類から約10種類にまで減り、Bugsnagはエラーがスパイクした時のみ対応することになりました。
また、slackの通知先チャンネルも緊急度で分割し、緊急度の高いアラートだけに注意が向けられるようにしました。さらにログインや新規登録、Pick、フィードの読み込み、課金などNewsPicksで重要な機能のAPIに対し、NewRelicでレスポンスタイムやエラー率の監視を新たに行うようにしました。
2. 当番ローテーションの変更
ラインをサーバ1 ・サーバ2・アプリ(=iOS/Android)に分け、ラインごとに専門分野のアラート+職能によらない共通のアラートのみ通知されるようにしました。同じ時間帯に複数人で通知を受ける体制にすることで、1人が通知に気づけなくても誰かがカバーできるようになりました。
3. PagerDutyの導入
緊急度の高いアラート発生時はslackに加えてPagerDutyで電話が鳴るようにしました。また、slackのスラッシュコマンド+API Gateway+AWS LambdaでslackからPagerDutyのインシデントをトリガーできるようにし、既存の監視ツールで拾いきれない障害報告もキャッチできるようにしました。
この2つの対応により、slackをチェックし続ける必要がなくなり、電話が鳴った場合だけ対応を行えば良くなりました。
この体制を導入しもうすぐ1年が経ちますが、SLO違反をする程のサービスレベルの低下は発生しておらず、当番メンバーからの改善要望も少なくなってきており、今のところはうまく回っているのではと思っています。
おわりに
NewsPicksのオンコール体制がどのように変わってきたかをご紹介しました。皆さんのオンコール体制はどのフェーズのものが近かったでしょうか?
今のNewsPicks開発チームでは最後の体制がワークしていますが、サービスの機能や開発基盤は日々アップデートされています。今後はSLOを活用した監視の強化やサブシステムへの展開なども視野に入れつつ、引き続き組織のフェーズや提供するサービスの性質に合わせてオンコール体制もアップデートしてきたいと思います。