この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
はじめに
AWSチームのすずきです。
AWSが提供するDNSサービスのRoute 53が備えるヘルスチェックを利用して、 Webサービスの月間の合計ダウンタイム時間を求め、 SLAなどの基準となる月間稼働率の計算を試みる機会がありましたので、紹介させて頂きます。
サービスダウンの定義
今回、ダウンタイムとしては以下の定義としました。
- AWS内に設置した計測システムから、特定のWebページ応答をHTTP/HTTPSで監視する
- HTTPレスポンスコード200番以外の異常応答、タイムアウト発生を異常応答とする
- 誤検知対策として計測システムは3台以上を用意し、2/3以上の異常が記録された時間帯をダウンタイムする
Route 53設定
今回対象とするWebサーバは、AWS東京リージョンのELBを利用するシステム。 ネットワーク的な遠さに起因する影響を抑えるため、東京、シンガポール、オレゴンの3リージョンを利用する方針としました。
サービスダウン判定イメージ
正常判定イメージ
- ヘルスチェッカーやその稼働リージョンの単独障害は、サービスダウンと判定しないものとしました。
エンドポイント設定
- 監視対象は固定IPアドレスを持たないサービス(ELB)である為、ドメイン名を指定としました。
オプション設定
2つのオプションを有効とし、AWSのエンドポイントを対象とした場合、月額1$×2件の追加費用が発生する設定としました。
- HTTPS監視
- レイテンシ監視
HTTPレスポンスコードだけでは確認が不足するケース、
- CMSなどで、不完全なコンテンツが生成される可能性がある
- エラー時のソーリーページがHTTPレスポンスコード200で戻す可能性がある
- APIのレスポンスボディに含まれる応答内容を含めた詳細な確認が望まれる、
などの場合には、レスポンスボディの先頭5120バイトを対象として指定文字列が出現しない事を異常と判定する「String matching」オプションの利用が有効です。
作成画面
動作確認
- Monitoring画面より、稼働率100%でなかった場合、ダウン時間の発生を確認できます。
- HelthCheckerの個別の稼働状況も確認が可能です
CloudWatch
CloudWatch ダッシュボード
- Route 53ヘルスチェックの結果は、バージニア(us-east-1)リージョンのCloudWatchメトリクスで確認可能です。
CLI (awscli)
CloudWatchメトリクス(HealthCheckPercentageHealthy)のJSONをawscliを利用して取得、 JSONデータを「jq」コマンドを利用した加工により、稼働率が2/3を下回る時間を求めました。
環境情報
- jq コマンドをインストールします。
sudo yum install jq
- 実行バージョンは以下の通りでした。
$ jq --version
jq-1.5
$ aws --version
aws-cli/1.14.9 Python/2.7.12 Linux/4.9.76-3.78.amzn1.x86_64 botocore/1.8.13
スクリプト
- Route 53 コンソールなどで集計対象のヘルスチェックIDを求めた上で、以下のスクリプトを実行しました。
# Route53ヘルスチェックID定義
HEALTHCHECK_ID='#############'
AWS_ACCESS_KEY_ID==#############
AWS_SECRET_ACCESS_KEY=#############
# 1日分のメトリクス取得
get_metrics_5min () {
n=$1
START_TIME="`date -d \"${n} day ago\" "+%Y-%m-%d"`T00:00:00"
END_TIME="`date -d \"${n} day ago\" "+%Y-%m-%d"`T23:59:59"
aws --region=us-east-1 \
cloudwatch get-metric-statistics \
--metric-name HealthCheckPercentageHealthy \
--start-time ${START_TIME} \
--end-time ${END_TIME} \
--period 300 \
--namespace AWS/Route53 --statistics Average \
--dimensions Name=HealthCheckId,Value=${HEALTHCHECK_ID} \
| jq -c '.Datapoints| sort_by(.Timestamp)|.[]'
}
# 1ヶ月分を処理
cat /dev/null > 5min.json
for i in {31..0} ; do
get_metrics_5min ${i} >> 5min.json
done
# 件数判定
TOTAL=`cat 5min.json | jq -c '[.Timestamp,.Average]' | wc -l`
OK=`cat 5min.json | jq -c '.|select(.Average >= 66.6)|[.Timestamp,.Average]' | wc -l`
NG=`cat 5min.json | jq -c '.|select(.Average < 66.6)|[.Timestamp,.Average]' | wc -l`
OK_RATE=`echo "scale=6; ${OK} / ${TOTAL} * 100" | bc`
NG_RATE=`echo "scale=6; ${NG} / ${TOTAL} * 100" | bc`
echo "Total: ${TOTAL}"
echo "OK rate: ${OK_RATE}"
echo "NG rate: ${NG_RATE}"
cat tmp.json | jq -c '.|select(.Average < 66.6)|[.Timestamp,.Average]'
実行例
- サンプル環境、計測回数9092中、ダウン判定されたのは7回でした。
- 今回の定義では、月間合計ダウンタイム時間は35分(7回×5分)、月間稼働率は99.923%の計算となりました。
$ echo "Total: ${TOTAL}"
Total: 9092
$ echo "OK rate: ${OK_RATE}"
OK rate: 99.923000
$ echo "NG rate: ${NG_RATE}"
NG rate: .076900
$ cat tmp.json | jq -c '.|select(.Average < 66.6)|[.Timestamp,.Average]'
["2018-02-06T16:00:00Z",63.96396396396396]
["2018-02-06T16:05:00Z",33.111111111111114]
["2018-02-06T16:10:00Z",26.1891592920354]
["2018-02-06T16:15:00Z",27.34375]
["2018-02-07T18:05:00Z",50.75]
["2018-02-07T18:10:00Z",62.138888888888886]
["2018-02-07T18:25:00Z",60.74561403508772]
まとめ
Route 53のヘルスチェックを設定し、そのCloudWatchメトリクスを集計する事で 月間合計ダウンタイム時間、SLAの指標としても利用される事の多い月間稼働率を取得する事ができました。
Route 53のヘルスチェックは、1エンドポイントあたり月額1〜数$の費用で利用でき、監視システムのサーバ管理からも開放されます。 SLAの合意要件を満たす場合には、その計測手段の一つとしてご活用ください。
今回はCLIを利用した簡易集計を紹介させて頂きましたが、今後、
- Lambda、Athenaなどを利用したサーバレスな集計計算の実現
- 基準時間の短縮、1分間のメトリクスを利用する方法
- SLAの指標となるレスポンスタイムの違反、Route 53 ヘルスチェックのレイテンシ監視や、ELBのレイテンシ情報などで計測
- 監視SaaS Datadogとの連携、ダッシュボード作成
などについても紹介させて頂ければと思います。