障害検知のための監視設計
はじめに
こんにちは。エムシーデジタルでソフトウェアエンジニアをしている松井です。
今回は、私が実際に担当したシステムを元にした比較的小規模な架空のシステムを題材に、システムの運用における監視の設計について考えてみようと思います。
本システムはアプリケーションの開発者がそのまま運用を担う体制となっており、監視の設計もアプリケーション開発者の目線で行います。
監視設計の流れ
システム運用において監視はほぼ必須になるかと思われます。
「監視」と一口に言ってもその目的はさまざまだと思いますが、ここでは「監視」の目的を、システムの障害あるいは障害につながりうる事象を検知することと定義します(今回は触れませんが、システムの利用状況、パフォーマンス、セキュリティインシデントや従量課金の発生費用等に対しても必要に応じて監視が行われるべきでしょう)。
1. システムの全体像・要件の把握
監視設計を行うにあたっては、当然ですが、まずシステムの構成要素を把握し、どのような要件が求められているかを理解する必要があります。
今回のシステムについては以下のように定義したいと思います。
システム概要
- 本システムは特定の業界の企業向けに SaaS として提供される Web アプリケーションです。
- システムは基幹業務をサポートするものとして補助的に利用されます。
- 数社に試験導入を行っている段階であり、この度正式にカットオーバーとなります。カットオーバー後も継続的に保守開発を行います。
- システムの運用はシステムの保守開発者が兼任します。開発者の人数は数名程度です。
アーキテクチャ
システムインフラには Google Cloud を採用しています。
- フロントエンドとバックエンドを担う Cloud Run サービスがそれぞれ存在し、Cloud Load balancing 経由で外部からアクセスされます。
- 静的コンテンツは Cloud Storage に保管します。
- 動的データは Cloud SQL に保管します。
- バッチプログラムは Cloud Composer によって実行されます。
要件
- バッチプログラムは平日の朝・昼に同様の処理がそれぞれ定期実行されます。
- 朝のバッチが 09:00 までに完了しない場合には業務に影響が出ます。
- 昼のバッチは参考情報作成としての処理となっており、業務に影響を与えません。
- Web アプリケーションは業務時間中(平日 09:00-18:00)のシステム稼働を求められており、それ以外の時間帯はサポートの範囲外です。
- クラウドサービスの障害によるシステムのダウンは SLA の計算におけるダウンタイムには含めないものとします。
2. 監視対象の選定
次に監視対象を選定します。
システムの全体像・要件から、何が障害につながるかという観点で選定を行います。
サービス・処理の監視(ユーザーにサービスが提供できているか)とインフラの監視(サービスを提供するための基盤が正常に稼働しているか)で分けて考えるのがよいでしょう。
サービス・処理の監視
サービスの提供ができなくなるとすなわちシステムの障害となります。提供対象となるサービス、およびサービスを提供するにあたって必要となるバックグラウンドの処理を特定します。
今回は以下のサービス・処理を監視対象として選出しました。
- Web アプリケーション
- バッチプログラム(朝)
- バッチプログラム(昼)
昼のバッチプログラム実行は失敗しても業務影響はなく、直ちに障害となるものではありませんが、長期的に処理が失敗し続ける状況は好ましくないため監視対象として選出しました。また、朝のバッチプログラムと同様の処理を行っているため、翌日朝の実行失敗を事前検知するためのカナリア的役割を果たしてくれることを期待しています。
インフラの監視
システムアーキテクチャ等を参考に、障害につながりうる重要なリソースを監視対象として選出します。
今回は以下のリソース/処理を監視対象として選出しました。
- Cloud Run (Frontend/Backend)
- Cloud SQL
- Cloud Composer
Cloud Load Balancing と Cloud Storage は監視対象から除外しています。これらのサービスダウンもシステムの障害につながりますが、クラウドプロバイダーによるマネージド比率が高いため、サービスダウンを検知したところで対処が難しく、また自動復旧するため除外しています。逆に、監視対象として選出したリソースについては、これらも同様にマネージドサービスではありますが、異常発生時に何らか運用側で対処を取る必要があるものと判断しました。
このほか、Google Cloudなどのクラウドサービス上でインフラを手配する場合は、作成できるリソースの上限値(クォータ)が決まっており、この上限値に達した場合に新たなリソースの手配ができず障害につながる場合があるため、リソースの利用量がクォータに近づいている/達していることの監視も検討に含めるべきです。今回のシステムはリソースの利用量が大きくないため監視の対象外とします。
3. 監視項目・監視方法の検討
監視対象を洗い出しましたので、次はそれらの対象に対してどのような項目の監視を行うか、またどのような手法で監視を行うかについて検討します。
また、ここで監視項目で検知する事象が、障害なのか、それとも障害の予兆なのかを分類しておくのがよいかと思います。障害・予兆についてはここでは以下のように定義します。
- 障害:文字通り障害の発生を意味します。
- 予兆:即座に障害となるものではないが、障害につながりうる事象の発生を意味します。
両者の対応緊急性は違うため、この後の監視通知の判断基準として利用します。
サービス・処理の監視
Webアプリケーション
監視項目 | 障害 or 予兆 | 監視方法 |
---|---|---|
Web アプリケーションが利用できること | 障害 | サーバーの正常応答レスポンスを確認するためのエンドポイントを用意し、平日業務時間中に定期的な死活監視を行う。 |
本来的にはログインして主要機能を実行するなどユーザー操作に近い形で外形監視を実現できるのが望ましいかと思います。実装の容易性から、今回は単純に正常レスポンスが返ってくることをもって Web アプリケーションが正常利用できるものとしています。
エラーログ監視について
アプリケーション自体はアクセス可能であったとしても特定の箇所で予期せぬエラーが発生し、業務に影響が出ている可能性があります。アプリケーションから出力されるエラーログを監視し、早期に対応を行うことはシステムの可用性を高める上で有効な対応といえます。今回は省略します。
バッチプログラム(朝・昼)
監視項目 | 障害 or 予兆 | 監視方法 |
---|---|---|
朝のバッチが異常終了していないこと | 障害 | 異常終了時にエラーログを出力し、ログ監視を行う |
朝のバッチが規定時間以内に完了していること | 障害 | 規定時間に監視プログラムを実行し、当日朝のバッチプログラムが正常終了していることを確認する |
朝のバッチが起動していること | 障害 | 規定時間に監視プログラムを実行し、当日朝のバッチプログラムが正常終了していることを確認する |
昼のバッチが異常終了していないこと | 予兆 | 異常終了時にエラーログを出力し、ログ監視を行う |
昼のバッチが起動していること | 予兆 | 規定時間に監視プログラムを実行し、当日昼のバッチプログラムが正常終了していることを確認する |
バッチが起動していないことには気づきにくいため、その観点で監視を行うのは大事かと思います。今回は規定時間以内に正常終了していることを確認することで合わせて確認を行うものとしています。
インフラの監視
監視対象 | 監視項目 | 障害 or 予兆 | 監視方法 |
---|---|---|---|
Cloud Run | インスタンスの数が長時間インスタンスの最大数に達していないこと | 予兆 | メトリクス監視 |
Cloud SQL | CPU使用率が長時間高い状態にない事 | 予兆 | メトリクス監視 |
Cloud Composer | Cloud Composer が稼働していること | 予兆 | ヘルスチェック DAG による死活監視 |
今回は上記を監視するものとしました。
個々のリソースについてはサービスの仕様に依存するため詳述を避けますが、以下のような観点で監視項目を追加していくことになるかと思われます。
- リソースが逼迫していないか
- オートスケールが正常に動作する状態になっているか
- 何らかの異常によりサービスが正常稼働していない状態になっていないか
- 著しいパフォーマンス悪化が起きていないか
4. 監視通知の設計
監視項目が決まったので、最後に監視項目の検知が行われた場合の通知方法について考えます。
今回のシステムでは以下のように設計しました。
監視項目 | 通知手段 | 通知先チャネル |
---|---|---|
障害の監視項目 | メール | ユーザー企業担当者のメールアドレス |
障害の監視項目 | Slack | #system-alert-error |
予兆の監視項目 | Slack | #system-alert-warning |
監視の文脈を少し外れますが、障害の監視検知が行われた場合には、ユーザー企業担当者のメールアドレスに対して自動的にシステム障害の通知を行うものとしています。
通知手段
代表的な通知方法は以下のものでしょう。
- Slack
- メール
- 電話
<Slack での監視通知サンプル>
必要に応じて複数の方法で通知を行うことも検討に含めてよいかと思います。
また、監視項目ごとにその重要度も違うため、必要に応じて同じ通知手段であったとしても通知チャネルを変えるのがよいでしょう。
障害に対してより堅固な運用を行うのであれば PagerDuty などのサービスの利用も検討に含めてよいかと思います。
通知に含めるべき情報
通知には以下のような情報を含めるのがよいと思います。
- タイトル
- 発生している状況を簡潔に表す。
- X: メトリクス XXX が閾値を超えています
- O: Cloud SQL インスタンス XXX の CPU 使用率が長時間高い状態にあります
- 発生している状況を簡潔に表す。
- エラーの状況・ログ等が確認できる URL 等
- 発生した環境 (prod, stg 等)
- (対応手順が確立されている場合)対処すべき手順あるいは手段が記された文書へのリンク
- (バッチプログラム等であれば)エラー発生までに処理できた件数など
おわりに
ここまでくれば監視の設計はひとまず完了です。
今回は小規模な運用体制であったため、障害の発生に対するリアクティブな対応を前提とした監視設計を行いましたが、より充実した運用体制であれば、ダッシュボード等を用意して障害を未然に防止するためのプロアクティブな活動を行うことも視野に入れてよいでしょう。
運用開始後のチューニングも必要に応じて実施していくことが重要かと思います。
以上、駆け足でしたが本記事の内容がどなたかの参考になれば幸いです。
エムシーデジタルでは、技術力向上のためのイベントや勉強会なども定期的に実施しています。 もしエムシーデジタルで働くことに興味を持っていただいた方がいらっしゃいましたら、カジュアル面談も受け付けておりますので、お気軽にお声掛けください! 採用情報や面談申込みはこちらから