サーバーレスアーキテクチャでモニタリングシステムを実現する
モニタリングシステムはサーバーレスアーキテクチャで実現されるべきである。
みなさんは自社のサービスを外のネットワークからE2Eで死活やパフォーマンスを確認したい場合に、どのようにそれを行っていますか?
モニタリングシステムと言えば今はZabbixが定番でしょうか。もしくはいくつかのOSSのモニタリングツールを組み合わせていたり、今風に有料のSaaSを利用していたりするのでしょうか。
ここではサーバーレスでアプリケーションパフォーマンスモニタリングを行うアーキテクチャを紹介します。
何故サーバーレスが良いのでしょうか?
サイトの単純なレスポンスタイムならよいですが、status.github.comページにあるような"MEAN HOOK DELIVERY TIME"など、hook実行までの経過時間やpush通知が届くまでの経過時間、kafkaのstream上のrecordがconsumeされるまでの経過時間を定期的に計測監視したい場合に、自前で計測のスクリプトやアプリケーションを書かなければいけません。*1
そして当然そのスクリプトやアプリケーション自身も何かしらでうまく動いているかどうかを監視・管理することになります。
つまり、
”「アプリケーションをモニタリングするためのアプリケーション」をモニタリングするためのアプリケーションをモニタリング...”
というように無限ループになってしまいます。
この無限ループから脱却するためには、
モニタリングアプリケーションをサーバーレスアーキテクチャで実現することで、マネージドサービス内でモニタリングの仕組みを完結させる
ように設計するのが最適なのではないかと考えたわけです。
言いたいことはほぼ言ってしまったのですが、一つの例としてserverlessを使って実装してみました。*2
ソースコードのサンプルはこちらです。とても小さく、計測部分はダミーのコードになっています。
ちなみにAPMはapplication performance managementの略です。
コードに関して特に説明することはないのですが、handler.pyに定義した2つの関数がメインになっています。
def monitor_response_time(event, context): elapsed_time = -1 try: elapsed_time = test_response() put_cloudwatch_metric('response_time', elapsed_time, get_current_region(context)) except Exception as e: print("Exception: " + str(e)) return elapsed_time def monitor_hook_delivery_time(event, context): elapsed_time = -1 try: elapsed_time = test_hook() put_cloudwatch_metric('hook_delivery_time', elapsed_time, get_current_region(context)) except Exception as e: print("Exception: " + str(e)) return elapsed_time
それぞれのパフォーマンス計測結果をCloudWatchのcustom metricsとして保存する流れになっています。
これらの関数はserverless.ymlに定義されており、それぞれLambda functionとしてデプロイされることになります。
functions: monitor_response_time: handler: handler.monitor_response_time description: 'Monitor response time' events: - schedule: description: 'Calling monitor_response_time function every minute' rate: rate(1 minute) monitor_hook_delivery_time: handler: handler.monitor_hook_delivery_time description: 'Monitor hook delivery time' events: - schedule: description: 'Calling monitor_hook_delivery_time function every minute' rate: rate(1 minute)
またそれぞれCloudWatch EventsのScheduleが設定されているため、毎分Lambda functionが呼び出される仕組みになっています。
デプロイは対象のディレクトリで serverless deploy
コマンドを実行するだけです。
$ serverless deploy Serverless: Creating Stack... Serverless: Checking Stack create progress... ..... Serverless: Stack create finished... Serverless: Packaging service... Serverless: Uploading CloudFormation file to S3... Serverless: Uploading service .zip file to S3 (8.11 KB)... Serverless: Updating Stack... Serverless: Checking Stack update progress... ...................... Serverless: Stack update finished... Service Information service: serverless-apm-example stage: dev region: ap-northeast-1 api keys: None endpoints: None functions: serverless-apm-example-dev-monitor_response_time: arn:aws:lambda:ap-northeast-1:************:function:serverless-apm-example-dev-monitor_response_time serverless-apm-example-dev-monitor_hook_delivery_time: arn:aws:lambda:ap-northeast-1:************:function:serverless-apm-example-dev-monitor_hook_delivery_time
とても簡単ですが、初めてAWS Lamdbaを使う場合は何が起きているかよくわからなくて逆に難しく感じるかもしれません。
裏側ではCloudFormation、S3、IAM Role、Lambda、CloudWatch Eventsなどを利用して関数がサーバーレスで動く環境が作られています。
Lambda
CloudWatch Events
ここまで自身で用意したのは handler.py
と serverless.yml
だけですね。
これだけでアプリケーションのパフォーマンス監視ができてしまうといっても過言ではありません。
さらにLambda自体も簡単にCloudWatchで監視・ログ確認・アラート通知などができますので、
この全体の仕組自体の監視がAWSのマネージドサービス上で完結できるわけです!
それでは保存したcustom metricsをCloudWatchのダッシュボードを作成し確認してみましょう。
必要であればしきい値を設定してアラート通知の設定をすることもできます。アラート通知はserverlessのツールでは設定できないのでマネージメントコンソールかAWS CLIなどを使ってください。
CloudWatchのcustom metricsに入れてしまいさえすれば、可視化にしろ通知にしろモニタリングとしては十分かなと思います。
少し話がそれますが、Grafanaを使うとよりcoolなダッシュボードを作ることができます。
GrafanaはデフォルトでCloudWatchをデータソースとして扱えるようになっており、
EC2にGrafanaをインストールする場合はそのインスタンスにCloudWatchにアクセス可能なIAM Roleを設定してあげるだけで、
CloudWatchの全てのmetricsのデータをGrafana上で可視化できます。
試しにローカルのDocker上でGrafanaを動かして先ほどのCloudWatchのデータを取り込むことで、このようなダッシュボードを作ることができます。しかも数分で。
やったのは docker run -i -p 3000:3000 grafana/grafana:4.1.1
とwebブラウザから http://localhost:3000
にアクセスしてadmin/adminでログインしてちょろっと設定しただけです。
前からGrafanaはただのグラフ化ツールだろうとあまり触れてこなかったのですが、
いざまともに使ってみるとデータソースの設定はとっても簡単でCloudWatchもZabbixもすぐ連携できますし、
LDAPログインの設定も簡単、そして何より単純なグラフがよりcoolに見えるだけですごく気持ちが良いというなかなか良いツールだと気づきました。
UI/UXだけでも選ぶ価値があるんだなということを再認識しました。
話をもとに戻して、今回サーバーレスアーキテクチャでアプリケーションパフォーマンスのモニタリングを実現する仕組みを紹介しました。
一言で言うならば、モニタリングする仕組みなんて面倒だから自分で管理したくないんだよ!ということでした。
サーバーレスアーキテクチャに興味がありつつなかなかどのシステムから導入してよいか迷って二の足を踏んでいる方は、
プロダクションコードとは別の庭であるモニタリングの部分からサーバーレスアーキテクチャを導入してみると、
相性が良くてうまくいきやすいのではないかなと思います。
それでは良いサーバーレスライフを。