Magic DashboardsでRubyアプリのパフォーマンス監視を強化する方法
アプリケーションチームにとって、顧客がどのような体験をしているのかを把握することは不可欠です。これは、ユーザビリティやレスポンスの良さといった全般的な観点だけでなく、日々の運用における一分一秒単位の変化についても当てはまります。
特に分散システムを扱う場合、エラーの発生は避けられません。サイトへのトラフィックは一日の中で変動し、システムが依存するコンポーネントのいずれにも、いつ問題が起きてもおかしくないからです。
本記事では、「マジックダッシュボード(Magic Dashboards)」を活用して、Ruby on Railsアプリケーションのパフォーマンス問題を監視・解決する方法を解説します。
マジックダッシュボードの詳細に入る前に、まずアプリ設計時に押さえておくべきポイントを確認しておきましょう。
Rubyアプリ開発時に考慮すべきこと
アプリケーションのオーナーやチームメンバーであれば、顧客が気づく前に問題を検知したいはずです。それにより即座に修正対応を行え、ユーザーへの影響を最小限に抑えられる可能性が高まります。
いつでも答えられるようにしておきたい、アプリケーションに関する重要な質問がいくつかあります。
- ページのレスポンスタイムは許容範囲内か?Googleによると、近年は2秒より遅いと顧客はサイトを離脱して他へ移ってしまうと言われています。
- ユーザーにエラーが発生していないか?発生している場合、どの種類のエラーか?エラー率はどの程度か?
- 進行中の運用上の問題がアプリケーションに影響を与えていないか?ネットワーク、ストレージ、セキュリティサービスなどが該当します。ご存じのとおり、クラウドプロバイダーの障害もアプリケーションの健全性に影響を及ぼします。
オブザーバビリティ(可観測性)は極めて重要でありながら、エンジニアが最後に考えてしまいがちなテーマです。「運用準備のための時間はスケジュールに組み込まれている」と言っても、それは実際には製品リリース前の週末だったりします。
冗談はさておき、監視対象となるアプリはまず作らなければ存在しません。そのため、パフォーマンステストは開発ライフサイクルの終盤に先送りされがちです。コードが完成していない段階で時間をかけてテストしても、後でやり直すことになるからです。
セキュリティテストも同様です。あまり早く実施すると、テスト後から本番投入前までの間に新たな脆弱性が混入する恐れがあります。
監視の重要性は分かっていても、これらの懸念には一理あります。その結果、監視はプロセスの終盤になってようやく注目されるのです。こうした課題を受けて、AppSignalはマジックダッシュボードを作りました。
AppSignalのマジックダッシュボードとは
AppSignalは、メトリクスやダッシュボード、アプリのパフォーマンスの重要性を深く理解しています。同時に、エンジニアにはリリース前にこれらに割ける時間がほとんどないことも分かっています。
マジックダッシュボードが「マジック」と呼ばれるのは、アプリと統合コンポーネントを接続するだけで、メトリクスの収集とそれに紐づくダッシュボードが自動的に作成されるからです。
実例で学ぶ:Ruby on Railsアプリの監視
それでは、マジックダッシュボードを使ってRuby on Railsアプリのパフォーマンス問題を監視・解決する流れを見ていきましょう。
サンプルアプリケーションは、暗号資産の価格予測にシンプルな機械学習モデルを使用します。非同期ジョブが毎日最新の価格データでモデルを更新し、精度を徐々に高めていく仕組みです。このRailsアプリにはWebページとREST APIの両方が含まれており、下図のようなアーキテクチャになっています。

Railsアプリをデプロイすると、RailsのPuma WebサーバーとSidekiqの非同期ジョブ向けのマジックダッシュボードが自動生成されます。その他のサポート対象の統合には、MongoDBやErlang VMなどもあります。
Pumaのマジックダッシュボードでは、スレッド数、プール容量、Pumaワーカー数に基づいてパフォーマンスを評価できます。Sidekiqのマジックダッシュボードでは、キューの長さ、キューの待ち時間、ジョブの実行時間、ジョブステータス、メモリ使用量を監視できます。
マジックダッシュボードは、Sidekiqジョブの実行のようなイベントベースのメトリクスや、分間プローブ(minutely probe)の使用状況をもとに自動検出・作成されます。minutely probe機能では、カスタムメトリクスをAppSignalへ送信するためのRubyブロックやクラスを登録できます。マジックダッシュボードはサポート対象コンポーネントに対してすぐに使える統合を提供しますが、この仕組みを利用すれば独自のカスタムメトリクスも送信可能です。
カスタムminutelyプローブの例
Sidekiqの統合はすでに組み込まれていますが、独自のバックグラウンドジョブ機構を監視したいケースもあるでしょう。その場合は、以下のクラス例を参考にできます。プローブクラスは接続を取得し、各呼び出しごとにその接続を使って必要なメトリクスを取得します。
Appsignal::Minutely.probes.register の呼び出しは、プローブ名とその実装という2つのパラメータを受け取ります。実装はlambda、または call メソッドを実装したクラスのいずれでも構いません。
AppSignalの設定とシステム要件
RailsアプリでAppSignalを使えば、マジックダッシュボードをすぐに利用できます。未導入の場合は、Gemfileにappsignal gemを追加してbundle installを実行してください。
続いて appsignal install コマンドを実行し、環境を設定します。設定内容はconfigファイルまたは環境変数に保存でき、これによってアプリケーションがAppSignalアカウントおよびダッシュボードに接続されます。
インストールしてサーバーを起動すると、次のようなメールが数通届きます。

この例のシステム要件は以下のとおりです。
- minutelyプローブをサポートするAppSignal gem 2.9.0以降
- Puma統合:バージョン3.11.4以降が必要
- Sidekiq統合:Redis gem 3.3.5以降が必要。AppSignal gemは2.9.5以降が推奨されます。
価格予測APIのパフォーマンステスト
サンプルアプリケーションは、Ruby FANN gemで実装したシンプルなニューラルネットワークを使って、翌日のビットコイン価格を予測します。直近10日間の価格変化率がモデルへの入力として使われます。
REST APIはパラメータを受け取らず、現時点では翌日の価格のみを予測します。出力は以下のようなシンプルなJSONドキュメントです。
Sidekiqジョブが毎日の開始時に市場価格を取得し、MLモデルを更新します。このジョブは5分ごとに実行されるようスケジュールされており、障害やエラーからの復旧を素早く行えるようになっています。
本記事のコードはすべてGitHubで公開しています。なお、本記事およびソフトウェアの内容は投資助言を構成するものではありません。暗号資産に関する投資判断の前に、必ずファイナンシャルアドバイザーにご相談ください。
パフォーマンステストにはJMeterを使用し、REST APIに負荷をかけてマジックダッシュボードで性能を評価します。最初のテストでは、同時接続クライアント5つがそれぞれ100リクエストを送信します。
統計を見ると、レスポンスタイムのばらつきがかなり大きく、平均342msに対してP99は852msでした。改善の余地がありそうです。

PumaマジックダッシュボードでRailsアプリのパフォーマンスを改善
Pumaのマジックダッシュボードにはスレッドプール容量のグラフが含まれており、テスト実行中にゼロに達しているのが分かります。これが一部のリクエストに時間がかかる原因と考えられるため、Pumaスレッド数を10に増やします。
注目すべきは、ダッシュボードやグラフの作成に何の手間もかけていない点です。すべてAppSignalが自動的に作成してくれました。

スレッド数を増やしてテストを再実行すると、レスポンスタイムは格段に安定し、ダッシュボードでもプール容量が許容範囲内に収まっていることが確認できます。

次は負荷を上げてみましょう。JMeterの同時接続クライアント数を50に増やし、ランプアップタイムを5秒に設定します。このテストではレスポンスタイムが悪化し、APIエラーも多数発生しました。Pumaのマジックダッシュボードでも、利用可能なPumaスレッドが再びゼロに達していることが示されています。
APIコードを確認すると、毎回データベースからモデルを読み込んでいることが判明しました。これは非効率なので、Sidekiqジョブを変更し、日次価格の取得に加えてMLモデルの実行と予測結果のDB保存も行うようにします。そして、この変更をデプロイします。
SidekiqマジックダッシュボードでAPIパフォーマンスをさらに向上
ここでSidekiqのマジックダッシュボードを確認してみましょう。残念ながらコードにバグがありましたが、少なくとも素早く特定して修正することができます。

Sidekiqの PriceUpdateJob が正常動作するようになったところで、API側を改修し、予測価格をデータベースから取得するだけで済むようにしました。これでAPIのパフォーマンスは向上しましたが、依然として一部のAPIエラーや長いレスポンスタイムが残っています。
再びPumaマジックダッシュボードへ
ダッシュボードを一目見ると、Pumaに追加ワーカーを設定していなかったことに気付きます。PumaワーカーはOSレベルのプロセスで、複数のスレッドを実行できます。総スレッド数は「ワーカー数 × 最大スレッド数」で計算されます。まず2ワーカーに設定しましたが、利用可能なスレッドがまだ枯渇するため、4ワーカーに増やします。

これでAPIのパフォーマンスは非常に良好になりました。平均レスポンスタイムは419msで、APIエラーも発生していません。

マジックダッシュボードでも、まだスレッドに十分な余裕があることが確認できます。

AppSignalのマジックダッシュボードのおかげで、Puma Webサーバーのキャパシティをリアルタイムに把握できるようになりました。SidekiqやActive Workerのダッシュボードも、アプリの非同期ジョブについて同様の洞察を提供してくれます。
マジックダッシュボードから得られた学び
Railsアプリのパフォーマンステスト中、Pumaマジックダッシュボードのおかげで、目標スループットに対してスレッド数が不足していたことを簡単に特定できました。スレッドプール容量、時間経過に伴うワーカー数、総スレッド数がひと目で分かります。
Sidekiqジョブ自体にはパフォーマンス上の問題はありませんでしたが、マジックダッシュボードのおかげでデプロイ後のエラーに素早く気付き、迅速に修正して再デプロイできました。これらの監視機能は、すべてAppSignalが自動的にセットアップしてくれたものです。
Ruby/Railsアプリ向けAppSignalのダッシュボード機能
AppSignalのダッシュボードには「web」アプリケーションや「background」ジョブといった名前空間があり、アプリの監視ビューを柔軟に多数作成できます。組み込みのサマリーダッシュボードでは、スループット、レスポンスタイム、最新のエラーなど、アプリ全体の健全性の概要を確認できます。
また、他のダッシュボードと同様に、表示するグラフやメトリクスの編集、レイアウトや選択したグラフの設定変更も自由に行えます。
異常検知も強力な機能です。空きメモリやエラー率などのメトリクス値が指定した閾値を超えた、または下回った際に通知を送る条件を定義できます。
まとめ:AppSignalで今すぐRubyアプリの監視を始めよう
オブザーバビリティとパフォーマンスは、アプリケーションの成功に不可欠です。しかし、つい後回しにしがちなテーマでもあります。
AppSignalのマジックダッシュボードは、自動セットアップされる豊富な標準搭載メトリクス、ダッシュボード、インサイトを提供します。これにより、アプリのパフォーマンスを迅速にチューニングし、運用準備状態へと到達できます。
AppSignal for Rubyの詳細については公式ドキュメントをご覧ください。
それでは次回も、ハッピーコーディング!
-
Ruby と Ruby on Rails の違いとは?初心者向けにわかりやすく解説
プログラミング初心者が混乱しやすい「Ruby」と「Ruby on Rails」開発の世界に足を踏み入れたばかりの方なら、数多くのプログラミング言語や専門用語に圧倒されてしまうかもしれません。Java、JavaScript、C、C#、C++——名前が似ている言語やアプローチは実にたくさんあります。その代表例が「Ruby と Ruby on Rails」です。この2つには違いがあるのでしょうか?そもそも何か関係があるのでしょうか?この記事では、そんな疑問にお答えします。Ruby と Ruby on Rails の関係性や、それぞれの役割についてわかりやすく解説していきます。Ruby の背景知識から
-
【Ruby入門】any?・all?・none?・one?メソッドで条件判定をスマートに書く方法
今回は、配列やハッシュなど、Enumerableモジュールをincludeしているオブジェクトに対して条件判定を行う際に役立つ、4つの便利なメソッド「all?」「none?」「any?」「one?」について解説します。 これらのメソッドは、いずれもtrueまたはfalseを返します。 それでは始めましょう! Rubyのall?メソッド 例えば、「配列内のすべての文字列が特定のサイズであるか」を確認したい場面を考えてみましょう。 素朴に書くと、このようになります: def all_words_have_specific_size?(words) return false if words.