Heroku Adevent Calendar 2018 の18日目の記事です。17日目はsilverskyvicto さんの「Heroku のアドオンを自作する方法を見てみた」でした。
なお、15日目は弊社代表取締役 黒川 幸治 による寄稿でした。 Re:Invent から帰ってきてすぐにHerokuの記事書いて…となかなか精力的なエンジニアっぽい感じですが、肩書は社長です。
Heroku の強み
Heroku を使いはじめてから気づく魅力の一つに、標準で用意されている機能の豊富さが挙げられます。たとえば Postgres/Redisアドオンや Github とのインテグレーション、Pipelines/Heroku CIでのCI/CD、CLIやAPIなどなど…
マネージドという言葉でIaaSプラットフォームもたくさんの機能を複雑な設定なく利用できるようになりましたが、開発者がプログラミングに集中する、それを実現するための万全な体制をプラットフォームが引き受ける。言うなれば引き算の美学は、まさしく Heroku が作り上げてきたものです。Heroku Metrics も同じ考え方の元で用意された標準機能の一つと考えられます。
今回紹介するHeroku Metrics は、ほとんど導入コストなしに、アプリケーションのパフォーマンス監視ないし必要に応じた通知を行える機能です。DynoやAddonのPlanを柔軟に変えられるためか、Metrics自体の機能をそのまま使わずにカットオーバーを目指しているプロジェクトを見かけることがあったので、どういうことができるんだろう・ひとまず使ってみましょうという思いから今回の記事を作成しました。
Heroku Metrics でできること
1. メトリクス監視
アプリケーションの 「Overview」の左上部にある「Metrics」が Heroku Metrics によるモニタリングレポート。イメージとしては Zabbix なり CloudWatchのダッシュボードに近いと思いますが、エージェントを設定したりダッシュボード自体を作る必要はなし。いくつかの手順を踏むだけで使えるようになります。
以下は、いくつかのダッシュボードの例です。管理者用サイト、マイページのデモサイト、ショッピングサイトと用途はそれぞれ。develop, staging, production の違いだったり、JVM , PHP, Ruby など言語の違いによってもある程度これらの数値は変わってきます。いずれにしても、アプリケーション開発者はほとんど何も実装や設定をせずに使い始めることができます。
メトリクス
以下のメトリクスが見られます。はじめは Events あたりで Platform のイベントと、Dyno restart などを見ながら、それ以外のメトリクスの動き方をじっくり眺めるのが良いんじゃないかと思います。
- Events
- Memory Usage
- Response Time
- Throughput
- Dyno Load
JVMメトリクス
アプリケーションのRuntime によって追加のメトリクスも用意されていて、JVM だと以下も追加で閲覧可能。
- Heap Memory Usage
- Non-Heap Memory Usage
- Aggregate Time Spent in Garbage Collection
- Aggregate Garbage Collections
設定の仕方
前述の通り、設定自体はほとんどすることがなく、 Dynoが動いていればダッシュボードに Metrics の情報が表示されるようになります。
対象のDynoの選択
上の選択リストで対象のDynoを選択。
メトリクス期間の選択
こちらの選択リストでメトリクスの期間を選択します。選べるのは「過去2時間/過去24時間/24~48時間前/48時間前〜72時間前/過去3日間/過去7日間」のいずれか。Cloud Watch が15ヶ月くらいだったと思いますが、稼働中だったりサービス稼動目標があるアプリなんかだとよほど遡及せざるを得ない理由が無い限り、そこまでの期間は必要ないですね。
メトリクスの設定
歯車アイコンからメトリクスの設定が可能で、ダッシュボードの見た目だったりRuntimeごとのメトリクスをここで有効化します。GAになっているJVM以外にも、2018/12時点で Public Beta の Ruby / Node.js。Dev Center の Getting Started 通り、適宜 push して様子を見ていればいつの間にかメトリクスに上がってくるようになります。
アラート(閾値・通知方法)の設定
「Configure Alerts」 から、Response Time と Failed Requestsについてはしきい値を設定して、超えた場合にメール通知を行うことも可能です。
AWS あたりだと、一度 SNS に渡してから LambdaなりSQSなりに繋げることが多いと思いますが、こちらは「アプリのMember全員に送信」「5通までの任意のメールアドレス」あとは PagerDuty に一度渡してポリシー適用というのが可能です。投げ先としては運用チームのメーリングリストなり、SlackのEmailAppを設定済みの監視Channelなりを選ぶのがシンプルだと思います。
ちょっとだけ注意したいのは、Addonをいくつか使っていると通知系が渋滞気味になるので、ちゃんと通知系の設定の粒を揃えておくべきということです。たとえばNewRelic/PagerDuty/Bugsnag/PapertrailとHerokuMetricsでそれぞれ通知の系があるのであれば、通知やサマリー送付などの頻度・条件を揃えておくか、ひと目でわかるように一覧化しておきましょう。時間差があると障害対応時に錯綜することがあるので。
ユースケース
1. 本番の稼動監視
アプリケーションの運用保守用途に使います。 PagerDutyやPingdom、Bugsnagと組み合わせることもありますが、基本的には Alert 設定までは必須で。設定先としては、上に挙げたような、監視用MLへの通知、Slackへの通知。
Alert の時間間隔は「1分/5分/10分」から選べますが、連携システムがある場合はそちらに合わせることが多いです。AWS側が詳細モニタリングを有効化しているなら、1分に合わせたり、など。
上に書いたメトリクス一覧のうち、見ることが圧倒的に多いのは Events と Throughput 。 Memory Usage とかは本番稼働後というよりは設計/実装時のサイジングの検証時に見ることが多いです。まず Events で事象や時系列を確認したら、 Throughput をみながら、問題箇所を特定していきます。
ポイントとしては、プラットフォーム/アーキテクチャレイヤーでの解決が可能かどうかの切り分けをすること。
もしDynoやAddonのPlanを変えてもエラーが出続ける場合は、ソースコードのロジックに何か問題がある場合があります。コードレベルの問題特定だったら、 NewRelic に任せましょう。…というと敷居が上がりそうなのですが、Heroku標準でここまでできている部分がほとんどで学習コストがほぼほぼゼロと言って良いものなのと、Heroku Metrics と NewRelic で役割分担ができるので、そこまで大変ではないと思います。RailsだとScout使うと良いって話もあるのですが、HerokuMetricsとNewRelicで慣れてしまっているならそれでも良いし、bullet とか特定用途で結構Gem入れちゃってたりすることもあると思うので、うまい棲み分けが正直知りたいところ。
2. 非機能系テスト用
パフォーマンステストと監視テスト、障害復旧テストあたりで使います。stagingまたはtest用環境を用意して、本番想定の状態でテストを行い、しきい値が適切か、きちんとアラートが飛ぶか、または通知後の復旧手順が正しく踏めたかを検証する際に利用します。
なお、必須ではないと思います。ミニマムプロジェクトや検証用途では必ずしも非機能周りはスコープになるとは限らないし、Heroku の拡張性や柔軟性の高さから、順次考えていけばよい、その時に設定すれば良い、という考え方もできるので。ただ、Dynoのコレクションについてはメモリやネットワーク、GPUなり特化型のインスタンスが用意されているというよりは事前定義済みのプランからの選択になるので、スケールアップ/ダウンの勘どころは IaaS と比べて少し変わってくるかなと思ってます。
最後に
- 早く容易に導入ができる(インフラ基盤、ミドルウェアまで提供されているため)
- 柔軟かつ早いスケーラビリティが実現できる
- 運用が容易にできる
- Salesforceとの親和性がよい 等々
Heroku Metrics は縁の下の力持ちな存在として、Herokuでのアプリケーション運用を支える重要なサービスであり、黒川が書いたようにHerokuを使う価値をわかりやすく体現した存在であると思います。簡単に使い始められるので、ぜひ使ってみてください。