こんにちは、トレタVPoEの北川です。 今回はトレタの開発組織で行っている監視業務(オンコール対応)について紹介しようと思います。
監視業務(オンコール対応)
トレタでは飲食店向けにサービスを提供しているため、飲食店の営業時間である深夜や土日祝にもシステムが利用されています。そのためトレタの営業時間外でも安定してサービスを提供できるように監視体制をつくり運用しています。
オンコールとは、システム障害が発生した際にオンコールの担当者が対応できるように待機する業務です。当番の担当者は障害発生時に障害状況の確認や各所への連絡を行います。
トレタではPagerDutyというサービスを使い、事前に定めたSLOの値を超えた場合に待機中の担当者に電話が鳴る仕組みとなっています。オンコール対応は当番制で365日11:00-24:00の時間に対応しています。担当者のルールとしては以下が定められています。
- 飲酒禁止
- 通信環境確保
- 機器携行
- 覚醒状態であること
簡潔に言うと、呼び出されたときに対応ができる状態であること、となります。それ以外に制約はないので、上記を満たしていれば家で動画を見ててもいいし、外に出掛けても問題はありません。
オンコール対応は業務の一部であるため当番にあたった担当者は会社から手当がつきます。 ただし、開発メンバー全員のオンコール対応への参加は必須にはしていません。プライベートな事情もあるので任意参加としています。
開発組織の方針としては、オンコール対応への参加は推奨としています。開発者は自分たちで作ったサービスの運用に責任を持つべきであり、どういったSLOで運用されるかを理解した上でシステム作りをすべきだからです。
逆に言うと、アラートが鳴らないようにシステム側が万全に対応されていれば、オンコール対応は待機するのみで緊急対応することなく手当を貰うことができます。エンジニアにとって「怠惰」は美徳という考えのもと、深夜や休日を心穏やかに過ごすためにシステムを整えておくモチベーションとして、オンコール対応の仕組みが働くのがこの制度のもう一つの目的です。
監視体制の仕組み化
上記の監視業務を行うには、システム側での監視の仕組み化が必要です。
- 障害が発生していることをシステムが検知できること
- オンコール担当者が状況を手早く確認できること
- オンコール担当者が対応を行える、または適切にエスカレーションできること
これらを構築するために必要なのがSLO / ダッシュボード / 対応マニュアルです。このセットは各アプリケーションや各マイクロサービスごとに整備します。
1. SLOを設定する
まずはシステムに異常がないかを検知するために、メトリクスと閾値を定義します。その閾値となるのが「SLO(Service Level Objective)」です。
監視するメトリクス
クライアントアプリケーションかサーバーかによって異なりますが、以下のメトリクスを設定することが多いです。
- 稼働率:システムが利用可能な状態になっているか
- 成功率:システムが正常に稼働しているか
- 応答速度:システムが期待通りの速さでレスポンスできているか
トレタの場合ではこれらのメトリクスをDatadogのSLOの機能を使って設定を行なっています。そしてDatadogのIntegrationを使い、メトリクスの閾値を超えるとPagerDutyへと通知が行われます。
稼働率
稼働率は主に外形監視を使った死活監視(ヘルスチェック)で計測しています。トレタの場合はMackerelというサービスを使い、事前に設定しているヘルスチェックのエンドポイントに対して定期的にリクエストを行い、エラーとなった場合には通知します。
ヘルスチェックには主に2種類のエンドポイントを設けています
- システム単体として応答するエンドポイント(
/_status_check
) - システム単体および依存するシステムの応答までを確認する、いわゆるDeepHealthCheckを行うエンドポイント(
/_health
)
Mackerelからは/_health
のエンドポイントをリクエストし、エンドポイント内では依存する内部システムのエンドポイント(/_status_check
)または外部システムのヘルスチェックエンドポイントへとリクエストを行います。
稼働率の閾値としては、基本的にサービス要求に基づいて設定を行いますが、理論値としては依存するシステムの稼働率が限界値となります。 例えば、CloudRunとCloudSQLを利用しているサーバーの場合、CloudRunの稼働率は99.95%以上であり、CloudSQLの稼働率も99.95%以上です。そのためそのサーバーの稼働率の限界は99.95×99.95の99.90%以上となります。さらにそのサーバーが別サービスを利用している場合にはその稼働率をさらに掛け合わせることになります。 これらは理論値なので、加えてシステム上のダウンタイムなどを加味するとさらに下げた値を現実的な閾値として設定します。
※ 2024年11月時点
成功率
サーバーとしてAPIを提供しているのであれば、成功率は以下で定義できます。
成功率 = 正常に応答したリクエスト数 / 全体のリクエスト数
「正常に応答した」とは、レスポンスのHTTPステータスコード2xx系/3xx系/4xx系のどれかであることとします。
成功率を監視することで、アプリケーションのリリースによりバグが埋めこまれたことや、依存するサービスに障害が起きていることを検知しやすくなります。 成功率の閾値をどうするかは、こちらもアプリケーションやサーバーの特性によります。より事業クリティカルな責務のシステムであれば閾値は高く定義する必要があります。
応答速度
サーバーの応答速度であればAPI Gatewayからレスポンスタイムのメトリクスを取得できます。 クライアントアプリケーションであればページ表示時間になります。 ページ表示時間はトレタの場合はWebページをVercelでホスティングすることが多いので、VercelのSpeed Insightsを使い、FirstContentfulPaint(FCP)やLargestContentfulPaint(LCP)を取得することができます。
2. Dashboardを作る
ダッシュボードは上記のSLOのメトリクスや、他にもサーバーなどの各種メトリクスを一覧化し、障害が発生した際にどこに異常があるかを見つけやすくするために役立ちます。
ダッシュボードに載せるべきメトリクスというのは一律で定めてはいませんが、サーバーで設定する一般的なメトリクスは主に下記になります。
APIサーバー
- CPU使用量
- メモリ使用量
DBサーバー
- CPU使用量
- メモリ使用量
- コネクション数
API Gateway
- リクエスト数
- 5xxレスポンス数
- レイテンシー
3. 対応マニュアル(Runbook)を用意する
「Runbook」と呼ぶことが多いですが、障害発生時にオンコール担当者がどのようにアクションをすればよいかをまとめたドキュメントです。
オンコール担当者がそのアプリケーションやシステムの直接の開発者でない場合でも適切な復旧作業が行えるように、具体的な指示を記載します。
- 各種アラートの説明
- 各種アラートがが鳴った時に確認すべきダッシュボードの項目
- メトリクスに異常がある場合の対応方法
対応方法としてはサーバー台数を増やしたりスペックの変更など、基本的にはGCPやAWSのコンソール上から操作できる内容を手順とあわせて記載します。
それらを行なっても回復しない場合は、最終的には担当開発者へのエスカレーションを行います。エスカレーションの際の連絡先(Slackでのチャンネル、メンバー)もRunbbokに記載が必要です。
さいごに
弊社ではマイクロサービスの構成にした際に、チームが分散されるのと各メンバーの守備範囲が分かれてしまうため、このように体系的な整備を行いました。 チームが拡大した時など、監視体制の検討をはじめた際にぜひ参考にしていただければ幸いです。