Cloud Run サービスに負荷テストを実施する
2023年は「Cloud Run を触って覚える」をテーマとした一人アドベントカレンダーを一人で開催しており、Cloud Run のさまざまな機能や、Cloud Run でよく使う構成などを実際の使い方と一緒にご紹介しています。
8日目は Cloud Run サービスに対して負荷テストを実施する手順についてご紹介します。
Cloud Run の概要は技術評論社さまのブログ「gihyo.jp」に寄稿した記事で解説していますのでこちらもぜひご覧ください。
Locust を使った負荷テストを実施する
この記事では Locust を使って負荷テストを実施する手順を紹介します。
この手順は Cloud Run ハンズオンとしても提供しており、GitHub リポジトリで公開しています。
この記事では、負荷テストの対象を以前ご紹介した Next.js アプリの Cloud Run サービスにしたいと思います。負荷テストを試す場合は、次の記事を参考にサンプルの Cloud Run サービスを予め用意してください。
構築は Cloud Shell 上で行います。試す際は負荷テストを実施する Google Cloud プロジェクトの Cloud Shell を起動し、作業を進めてください。
GKE Autopilot クラスタの構築
Locust の環境として GKE Autopilot を使用します。
まずは Kubernates Engine API を有効化します。次のコマンドで有効化できます。
$ gcloud services enable container.googleapis.com
次のコマンドで loadtest
という名前の GKE クラスタを構築します。
$ gcloud container clusters create-auto loadtest \
--region asia-northeast1 --async
クラスタは構築するまで数分かかります。数分後、次のコマンドで出力結果が RUNNING
になっていることを確認します。
$ gcloud container clusters list --format json | jq -r '.[].status'
コンソールで確認する形でも問題ありません。
クラスタ作成完了後、Kubernetes を操作するための認証情報を取得しておきます。
$ gcloud container clusters get-credentials loadtest --region asia-northeast1
Locust のデプロイ
Kubernetes 上で動かすため、helm を使い Locust を導入します。
$ helm repo add deliveryhero https://charts.deliveryhero.io/
main.py
ファイルを作成します。このファイルは負荷テストのシナリオに使います。
from locust import HttpUser, task
class HelloWorldUser(HttpUser):
@task
def hello_world(self):
self.client.get("")
main.py
ファイルを Kubernetes の configmap に登録します。
$ kubectl create configmap loadtest-locustfile --from-file main.py
Cloud Run サービスのエンドポイント URL を RUN_URL
というシェル変数に記録しておきます。Cloud Run サービスは hello
という名前が前提になっているので、違う名前の Cloud Run サービスを対象とする場合は変更してください。
$ RUN_URL=$(gcloud run services describe hello --region asia-northeast1 --format json | jq -r '.status.address.url')
次のコマンドで Locust をインストールします。
$ helm install locust \
deliveryhero/locust \
--set loadtest.locust_locustfile_configmap=loadtest-locustfile \
--set loadtest.name=loadtest \
--set worker.replicas=2 \
--set loadtest.locust_host=${RUN_URL}
次のコマンドを実行し Pod が稼働状態(Running)になるまで待ちます。
$ watch -n 5 kubectl get pods
すべての Pod で STATUS が Running``READY
が 1/1 になったら、Ctrl+C で抜けます。
Every 5.0s: kubectl get pods cs-410433091119-default: Fri Dec 8 05:32:46 2023
NAME READY STATUS RESTARTS AGE
locust-master-6d598b584b-jv96l 1/1 Running 0 7m38s
locust-worker-75fffdfb8-45529 1/1 Running 0 7m38s
locust-worker-75fffdfb8-sn9fl 1/1 Running 0 7m38s
Locust にはポートフォワードを通して UI にアクセスします。Cloud Shell への 8080
ポートへのアクセスを、Locust のポート 8089
に転送する設定を行います。
$ kubectl --namespace default port-forward service/locust 8080:8089
Cloud Shell で [ウェブでプレビュー] をクリックすると Locust のコンソール画面を開くことができます。
負荷ツールの Locust を GKE Autopilot 上に構築できました。
Locust からの負荷テストの実施
Locust の UI にて下記の数値を入力後 Start swarming
をクリックします。
- Number of total users:
1500
- Spawn rate:
30
1 秒あたりアクセスが 30 ユーザー増加し、最終的に 1500 ユーザーがアクセスしている状態をシミュレートしています。[Charts] タブを開くと、ユーザー数の増加がリアルタイムで確認できます。
Cloud Run サービスの負荷状況の確認
コンテナインスタンスの数、レイテンシ、CPU、メモリなどのメトリクスは Cloud Run サービスの詳細画面の [指標] タブから確認できます。
この記事で負荷テストの対象にした Cloud Run サービスは下記の設定にしています。
項目 | 設定値 |
---|---|
CPU 上限 | 1 |
メモリ上限 | 512 MiB |
同時実行数 | 80 |
メトリクスを確認してみます。もっとも負荷が多い時間帯のリクエスト数 (RPS、秒間リクエスト数) は約 480/s
となっています。
一方、コンテナ インスタンス数は 6
となっています。同時実行数は 80
に設定しているので、1台が 80
リクエストを処理するため 6 * 80 = 480
で概ね設定値通りにリクエストを処理できていることが確認できます。
負荷テストに関する参考情報
Cloud Run の負荷テストのベスト プラクティス
Cloud Run サービスの負荷テストのベスト プラクティスについてのドキュメントを公開しています。このドキュメントで、負荷テストを実施する上で考慮すべきことが学べます。
Cloud Run による I/O Adventure の負荷テスト
Google I/O 2022 イベント中に公開していた、バーチャルな世界を楽しめる「I/O Adventure」の WebSocket の同時接続テストをどのように実施したのか解説しているブログです。アプリケーション自体は GKE で構築していますが、負荷をかけるクライアント (ロード インジェクタ) に Cloud Run を活用しています。
この記事のテーマとは少しずれますが、負荷テストの手法として面白いのでぜひご覧ください。
まとめ
Cloud Run サービスの負荷テストを実施することで想定のトラフィックが発生した際のアプリケーションの挙動を確認することができます。Cloud Run で構築するサービスのトラフィックがある程度見込まれる場合は実施することをお勧めします。
Discussion