読者です 読者をやめる 読者になる 読者になる

ボクココ

サービス開発を成功させるまでの歩み

Heroku x Rails のサービスを本番運用する際に確認したいこと

ども、@kimihom です。

私は Heroku に Rails サーバーを立ててサービスを運用している。これまでの経験を元に、定期的にチェックしておきたい指標とか項目をまとめてみる。今後のサービス開発などで参考になれば幸いだ。

サービス構成

現在の構成はというと、以下のような感じである。

  • Ruby 2.4.1 (執筆時点で最新)
  • Ruby on Rails 4.2.8
  • Heroku Standard 1X Dyno * 4
  • Heroku Postgres Standard 0
  • Heroku Redis Premium 0

もちろん他にも使っているのはいろいろあるけど、ベースは上記のように至って標準な作りになっている。これによってインフラ周りでトラブルが起きることを最小限にとどめている。今現在でもインフラ周りで特別に問題になっていることはないので、これからも 上記の構成を使い続けていく予定だ。

では上記のような環境の中で確認したいことについてまとめてみる。

Heroku のメモリの項目をチェック

まずはサービスがメモリを使い過ぎていないかを定期的にチェックしよう。Professional Dyno にすれば、Heroku 内で “Meterics” の項目が見られるようになる。

f:id:cevid_cpp:20170505214402p:plain

ここでたまに線がガクッと下がっているのは Heroku が1日1回、自動で再起動されるためだ。この時にメモリは一旦リフレッシュされ、ちょくちょく溜まってたメモリを落としてくれる。この1日一回の再起動があるから、 Dyno を 2つ以上に保っておかないと、その一瞬はユーザーがアクセスできない時間ができてしまう。常にアクセスできるようにするために、そして 1つ Dyno が落ちても問題ないように、基本的に本番環境では Standard Dyno を2つ 常時起動にしておいた方がいいだろう。

さて、この図の上限の 100% を超えてしまうと、スワップ領域(上図中の下部紫エリア)にメモリを退避するようになり、めちゃめちゃレスポンス速度が遅くなるのでサービスのパフォーマンスに深刻な影響を及ぼすことになる。てことで メモリが 100% を超えないか、定期的にチェックしておく必要がある。ちなみに 100% を超えると、 Heroku のログに大量の R14 ログが吐き出される。

じゃあどうやってそのメモリを低く保てばいいのかってのが、Heroku のブログで丁寧にまとめられているので、これは必ず一読しておこう。ちなみに色々やって一番効果的なのは、定期的な Ruby のアップデート だった。

devcenter.heroku.com

上記の記事を元に記事を書いたこともあるので、上記ページの英語が嫌いな人は見てみるといいかもしれない。

www.bokukoko.info

Heroku のスループットとレスポンスタイムをチェック

同じく Heroku の Metrics でスループットとレスポンスタイムをチェックしよう。

これは例えば、あなたの運営するサービスが “夕方の15時にピークタイムを迎える” などの傾向を把握する上で必要になる。ピークタイムで例えば秒間50アクセスとか来ると、同時に全てのアクセスを処理できないのでリクエストの一部は待たされることになる。当然そうなると Metrics のレスポンスタイムがその時間に上昇するので、これは何か対策せんといかんな、という具合に管理することが可能だ。

ほとんどの場合、これは Dyno を増やすことで対応が可能だ。ただ、ずっと Dyno を増やしっぱなしにするのはお金が勿体無い。深夜帯なんてほとんどアクセスがこない場合がほとんどだと思う。そんな時は Process Scheduler などのアドオンを利用しよう。ピーク帯のアクセスはほとんど決まっていて、その時間に Dyno を増やせばいいと大体把握している場合は Process Scheduler は便利だ。これが例えばピーク帯が予想できないようなサービスの場合は、Adapt Scale などのアドオンを検討することになるだろう。

Rails のメトリクスは Scout がオススメ

Rails アプリ側のメトリクスツールは、 先ほどの Heroku ブログにも紹介されている Scout がオススメだ。NewRelic よりも軽く、より Rails に特化して表示してくれる。

どのリクエストに平均どのくらいのレスポンス時間がかかっているのかを簡単にチェックすることができる。どこから改善していけばいいのかがすぐにわかるので、Rails アプリを本番運用する際にはメトリクスツールは必須になる。

Heroku の メモリのチャートを眺めていると、たまにヒョンっとメモリが急上昇することがある。これは Rails アプリでたまに生じる Memory Broat と呼ばれるもので、特定のコードが無駄な処理(例えば N+1 のクエリ) を実行することで処理に多くの時間を費やしてメモリが急上昇するものだ。この場合は Rails のソースコードを修正する必要がある。その具体的な方法は、Scout のブログを参照していただきたい。もしくは先ほど紹介した “Heroku on Rails アプリのメモリ増加対策の方法” にもちょろっと紹介してある。

Scout のフリープランは割とすぐにリミット行っちゃってすぐアップグレードしろってメールくるのでそこは注意。

Heroku Postgres や Redis もたまにはチェック

基本的に Scout のメトリクスで DB 周りの大体のことも把握できるのだけども、それ以外でチェックしないといけないこともある。

特に Heroku Postgres はプランによって色々と制限があるので、その制限を超えていないかを定期的にチェックしないといけない。

Heroku Postgres の Standard-0 の場合、コネクション数の上限は 120 だ(これを超えるってことはほとんどないとは思うが)。また、ストレージの上限は 64GB である。まぁ Standard-0 にアップグレードすればほとんどのサービスでは当分困ることはないとは思うが、予期せぬ事態に陥らないように、定期的に Heroku Postgres のページにもアクセスするようにしたいところだ。

Heroku Postgres のページでも遅いクエリを発行しているものが何なのかを教えてくれたりするので、 Scout の結果と合わせてどれを直さないといけないのかを確認するようにしよう。

Heroku Redis も有料プランにあげればほとんどの場合問題になることはないとは思うが、定期的にメモリや接続数を使い過ぎていないか等を見に行くようにしよう。 Redis の初期設定はちょっと注意が必要なので以前書いた記事を紹介しておく。

www.bokukoko.info

最後は安定の Papertrail

もはや Heroku を使っている方にとってはスタンダードとなりつつある Papertrail

Papertrail のアラート機能を使って、エラーが起きたら迅速に Slack 等に通知する仕組みを用意しておこう。例えば Papertrail の検索条件を "Error" AND -"RoutingError" で保存し、アラートで “Error” の検索がヒットした時に Slack に飛ばすようにしよう。

これでアプリケーションレベルのエラーをすぐに検知することが可能だ。

それ以外にもアプリケーションログで重要なイベントは何でも通知できるようにしておくと、ユーザーの動向に基づいた素早い行動ができるようになるのでじゃんじゃんセットしておくといい。これはお金を払ってでも使っていきたいサービスだ。

終わりに

以上が私が Heroku を本番運用している中で定期的にチェックしている項目だ。一部は以前紹介したことのある Tips ではあるが、改めて全体をまとめとして紹介した。

Rails のレールと Heroku のレールに乗れば、Web サービスを極少人数で運用できる体制が実現できる。

最後に Heroku に興味を持った方は、ぜひ Japan Heroku User Group にジョイン!