
Cloud Run運用術:遅延も異常も見逃さない監視と通知

IT技術
今日からできる!Cloud Runサービスの運用のコツ

こんにちは、最近、個人開発用のMacBookPro(M4)を新調し、バッテリーの持ちの良さに感動した "こやまん" です。
今回は、Google Cloudの運用で役立つロギング、トレース、モニタリングアラートについて解説します。
ユーザー体験を左右する「レイテンシ」とは?速さが価値になる
ウェブサービスを運用する上で、特に注目したいのがリクエストのレイテンシです。
もしレイテンシが遅いと、せっかく良いサービスでもユーザーは離れてしまいます。
時は金なりとも言いますね。
レイテンシのざっくりした分類は次の通りです。
100ms(0.1秒)未満 | 理想的な応答速度。「ほぼ瞬時」と感じる |
100〜200ms | 快適なライン。ストレスを感じにくい |
200〜500ms | 許容範囲。やや遅く感じる場合も |
500ms〜1秒 | 「待たされている」と感じ始める |
1秒以上 | 明確に遅い。離脱や不満の原因になりやすい |
レイテンシは複数のステップで発生します。
例えば、「ユーザーの操作」から始まり、「ネットワーク遅延(リクエスト送信時)」が続きます。
その後、「Cloud Runアプリでの処理」を経て、「ネットワーク遅延(レスポンス受信時)」、最後に「ブラウザでの描画やJavaScript実行」という流れです。
ユーザーの操作
↓
ネットワーク遅延(リクエスト送信時)
↓
Cloud Runアプリでの処理
↓
ネットワーク遅延(レスポンス受信時)
↓
ブラウザでの描画やJavaScript実行
このうちCloud Runアプリの処理は、もっとも直接的にサービス全体へ影響します。
さらに、ネットワーク遅延もGoogle Cloudの設計次第で変わります。
Cloud RunのURLに対してcurlコマンドを使うと、「ユーザーの操作」と「ブラウザの描画」を除いたリクエスト送信からレスポンス受信までのレイテンシを計測できます。
1curl -o /dev/null -s -w "%{time_total}\n" 【Cloud Run の URL】
ちなみに、Cloud Runはリージョン選択も可能です。利用者に近いリージョンを選べば、ネットワーク遅延をより抑えることができるでしょう。
今回はcurlコマンドでデモコンテナに複数回リクエストを送り、応答速度を比較しました。
その結果、東京リージョンでは69 〜 110ms、ベルギーリージョンでは291 〜 518ms となりました。
Cloud Loggingで把握!実際のレスポンス速度
このように、レイテンシはcurlで計測できますが、サービス運用では、Cloud Run 自体のレイテンシを確認できるCloud Loggingも強力なツールです。
リクエストごとにレイテンシを記録できるため、運用現場では高い確率で活用されます。
実際に、以下のクエリでリクエスト単位のログを抽出できます。
1resource.type="cloud_run_revision"
2logName="projects/【Google CLoudのプロジェクト名】/logs/run.googleapis.com%2Frequests"
上記の画像の赤枠内がリクエストに対するレイテンシです。
デモコンテナ(hello)をデプロイした Cloud Run の場合、2ms ~ 10ms のレイテンシとなっています。
一方で、Rails8で簡単な文字を表示する検証アプリをデプロイした Cloud Run の場合、8ms ~ 166msとなりました。
ロギングではリクエストに対する Cloud Run の全体のレイテンシは分かりますが、個々の処理のどこに時間がかかったかまでは見えにくいです。
Cloud Traceで徹底分析!ボトルネックの正体を暴く
アプリケーションがリクエストを処理するのにどのくらい時間がかかるか?
アプリケーションがリクエストを処理するのになぜそんなに時間がかかるのか?
一部のリクエストが他のリクエストより時間がかかるのはなぜか?
アプリケーションへのリクエストの全体的なレイテンシは?
アプリケーションのレイテンシは時間とともに増加しているのか、減少しているのか?
アプリケーションのレイテンシを小さくするにはどうすればよいか?
アプリケーションにどのような依存関係があるか?
Cloud Run で各処理にどれだけ時間がかかったかを確認するのに便利なのが Cloud Trace です。
試しに、検証用のアプリケーションをデプロイして、動かしてみたいと思います。
まず、Cloud TraceにCloud Runのトレース情報を出力する準備をしましょう。
Google Cloudコンソールで次の設定を行います。
- Cloud Trace API を有効にする
- Cloud Run のサービスアカウントに「Cloud Trace エージェント」のロールを付与する
その後、Railsアプリケーションの準備に進みます。
今回の記事では、以下のバージョンとデータベースを使用しています。
- Rails 8.0.2
- Ruby 3.4.4
- DB : PostgreSQL
Gemfileには、以下の3つのGemを追加します。
1# Gemfile (注:他の行は省略しています)
2gem 'opentelemetry-sdk'
3gem 'opentelemetry-instrumentation-all'
4gem 'opentelemetry-exporter-google_cloud_trace'
RailsやActiveRecordなどの全自動トレースを有効化し、OpenTelemetry経由で収集したトレースデータをバッチ処理でGoogle Cloud Traceに送信する初期化処理を実装します。
本来であれば、初期化処理でサービス名も指定することで、Cloud Traceに出力できると思うのですが、2025年6月時点ではうまく動作しなかったため省略しています。
1# OpenTelemetry SDKの主要機能
2require "opentelemetry/sdk"
3# OpenTelemetryのすべてのライブラリやフレームワーク用のトレーシングコードを有効化
4require "opentelemetry/instrumentation/all"
5# Google Cloud Traceへのデータ送信用エクスポーター
6require "opentelemetry/exporter/google_cloud_trace"
7
8OpenTelemetry::SDK.configure do |c|
9 c.add_span_processor(
10 # トレースデータを個別に送信せず一定数、もしくは一定の時間間隔で送信
11 OpenTelemetry::SDK::Trace::Export::BatchSpanProcessor.new(
12 # OpenTelemetryが収集したトレースデータをGoogle Cloud Traceに送信
13 OpenTelemetry::Exporter::GoogleCloudTrace::SpanExporter.new
14 )
15 )
16 # OpenTelemetryの全てのライブラリやフレームワーク用のトレーシングコードを有効化
17 c.use_all()
18end
Cloud Run の URLにアクセスした際に、homeコントローラーのindexアクションが呼び出されるようにします。
1# config/routes.rb
2Rails.application.routes.draw do
3 root "home#index"
4 get "up" => "rails/health#show", as: :rails_health_check
5end
特定のブロックの処理時間の測定を行う場合は、カスタムスパンという機能を利用します。
indexアクション内にカスタムスパンを設定し、Cloud Traceで3秒のカスタムスパンが表示されるようにします。
1# app/controllers/home_controller.rb
2class HomeController < ApplicationController
3 def index
4 tracer = OpenTelemetry.tracer_provider.tracer
5
6 span_name = "カスタムスパン : #{controller_name}##{action_name}"
7 tracer.in_span(span_name) do |span|
8 # Cloud Traceが機能していることを確認するため、意図的に3秒停止
9 sleep 3
10 end
11 end
12end
表示用のテンプレートファイルを作成します。
1# app/views/home/index.html.erb
2<h1>Home#index</h1>
3<p>Find me in app/views/home/index.html.erb</p>
最後に、Cloud Run にデプロイして動かすために、Dockerfile を作成します。
1# Dockerfile
2FROM ruby:3.4.4
3
4# 必要なシステムパッケージを追加
5RUN apt-get update -qq && \
6 apt-get install -y --no-install-recommends \
7 build-essential \
8 libpq-dev \
9 nodejs \
10 yarn \
11 tzdata \
12 && rm -rf /var/lib/apt/lists/*
13
14WORKDIR /app
15COPY Gemfile Gemfile.lock ./
16
17# 非推奨フラグを使わずbundlerの設定で除外グループを指定
18RUN bundle config set without 'development test' && \
19 bundle install && \
20 bundle clean --force
21
22COPY . .
23
24# アセットプリコンパイル
25RUN bundle exec rails assets:precompile
26
27EXPOSE 8080
28ENV RAILS_ENV=production
29ENV RAILS_LOG_TO_STDOUT=1
30
31CMD ["bundle", "exec", "rails", "server", "-b", "0.0.0.0", "-p", "8080"]
ここまでで、Railsアプリケーションの準備は整いました。
続いて、Cloud Run へのデプロイを進めていきます。
以下の3点は完了している前提で進めていきます。
- Artifact Registryに【任意のリポジトリ】を作成済みであること
- Cloud Runにサービスを作成済みであること
- ローカルに gcloud SDKを導入し、プロジェクトの接続設定が済んでいること
デプロイする方法はいくつかあるのですが、今回は検証ということで、gcloudコマンドでささっと実行します。
はじめに、現在のディレクトリのソースコードからDockerイメージをビルドし、Google Artifact Registryにアップロードします。
1gcloud builds submit --tag asia-northeast1-docker.pkg.dev/【Google Cloud の プロジェクトID】/【任意のリポジトリ】/【任意の名前】
続いて、Cloud Runにデプロイを行います。
1gcloud run deploy 【Cloud Run のサービス名】 \
2 --image asia-northeast1-docker.pkg.dev/【Google Cloud の プロジェクトID】/【任意のリポジトリ】/【任意の名前】 \
3 --region asia-northeast1 \
4 --platform managed
デプロイが完了したら、Cloud Run の URLにアクセスします。
上記のようなビューファイルが表示されていることが確認できたら、Google Cloud のコンソールより、Cloud Trace を確認します。
上記の画像の通り、設定したカスタムスパンが表示されており、処理の時間も約3秒となっていることが確認できます。
また、ビューのレンダリングの処理に54.617ミリ秒かかっていることなども確認でき、Cloud Run のレイテンシの内訳が確認できることで、ボトルネックが特定しやすくなります。
なお、Cloud Traceでは全てのリクエストが必ずトレースされるわけではありません。トレースデータは標準ではサンプリング(間引き)されており、一部のリクエストのみが記録対象となります。必要に応じてサンプリング率の調整も可能ですが、詳細は公式ドキュメントをご参照ください。
異常を即キャッチ!モニタリングアラートで安心運用
毎回、サービスのレイテンシを目視で確認するのは手間がかかり、見落としも多くなってしまい現実的ではありません。
そこで、活用できるのが、特定の条件を満たした場合に、メールやSlackなどに通知を送れるモニタリングのアラート機能です。
アラートには、大きく分けて2つのベースに沿ったアラートがあります。
指標ベースのアラート | サービス全体の状態を数値で定期的に監視するアラート |
ログベースのアラート | 特定のログ内容や異常なイベント発生時に反応するアラート |
全体の傾向を監視したい場合は「指標ベース」単発でも見落としたくない場合は「ログベース」のアラートを利用します。
例えば、利用者の半数のレイテンシが1秒を上回ったらアラートを発生させる場合は「指標ベース」、1人でもレイテンシが1秒を上回ったことを検知したいのであれば「ログベース」となります。
私が携わったプロジェクトでは、指標ベースのアラートで、メモリーやCPUの使用率の監視を行いつつ、ログベースのアラートで、緊急性の高いエラーを監視するなどしてました。
エラーログに関しては、エラーレポートという機能もありますが、今回は割愛します。
ログベースのアラートについては、特に簡単に設定できます。
Google Cloud のコンソール画面でロギングを開き、以下のクエリを入力し、クエリを実行すると レイテンシが1秒以上の Cloud Run のリクエストログが抽出されます。
1resource.type="cloud_run_revision"
2logName="projects/koyama-study/logs/run.googleapis.com%2Frequests"
3httpRequest.latency>"1000ms"
この時、コンソール右側の操作より、ログアラートの作成をクリックすることで、ログベースのアラートを作成することが出来ます。
クエリの条件を満たすログ、つまり今回で言うと Cloud Run のレイテンシが1秒以上のリクエストログが発生した場合に、メールやSlackなどの任意の通知先にアラートを送ることができます。
アラートには自由なメッセージを設定できるため、発生時の対応方法をあらかじめ記載しておくと、運用がより明確になります。
アラートは簡単に増やせる一方で、設定しすぎると通知が多くなり、運用が形骸化してしまう恐れもあります。
本当に必要なアラートだけを厳選し、発生時には具体的な対応策を講じられるよう準備しておくことが、効果的な運用につながります。
まとめ
今回は、Google Cloud の運用で役立つ、ロギング、トレース、モニタリングアラートについてレイテンシを意識しながら触れてみました。
実際には、データベースや外部サービスとの通信など様々な要素が絡み合い、レイテンシの改善も容易ではありませんが、Google Cloudのサービスを有効に活用し、より良いサービスの運用が出来ればと考えています。
Cloud Run の運用については、Cloud Runで取得できる各種指標(CPU、メモリ、リクエスト数など)も重要なので、よろしければ CloudRunの指標について調べてみた! もご一読ください。
ライトコードでは、エンジニアを積極採用中!
ライトコードでは、エンジニアを積極採用しています!社長と一杯しながらお話しする機会もご用意しております。そのほかカジュアル面談等もございますので、くわしくは採用情報をご確認ください。
採用情報へ