負荷テストとは?
新しいアプリケーションや機能は、ほとんどの場合、ユーザーによるアクセスや利用が始まったばかりのときにはとても順調に動作しているものです。 しかし、ユーザー ベースが拡大し使用量が増えると、当初のインフラストラクチャではアプリを支えられなくなり、 ユーザーがパフォーマンスの低下を感じるようになります。 待ち時間が増え、帯域幅やメモリはあっという間に使い尽くされ、コード アーキテクチャの一部でエラーが発生するようになってしまいます。原因は、ユーザー数の増加に合わせてインフラストラクチャが適切にスケーリングされていないことにあります。 これは予想外の事態ではありません。インフラストラクチャとアプリケーション アーキテクチャは、使用量の増加に合わせてスケーリングする必要があるものだからです。 問題は、サーバーへの負荷の増加が原因でアプリケーションがいつ “壊れて” しまうのか、インフラストラクチャがいつダウンするのかが、事前にわからないことです。 特に金銭面で、大きな損失につながりかねません。
そのため、ソフトウェア アプリケーション ライフサイクルでは、負荷テストが最も重要なテストの 1 つとされています。 負荷テストでは、本番環境で想定される負荷をアプリケーションにかけます。 このテストで得た情報に基づいて、アプリケーションのパフォーマンスがしきい値を下回ることがないように、インフラストラクチャとアプリケーションを調整できます。
本チュートリアルでは、Apache Benchmark という HTTP サーバー用の負荷テストとベンチマーク ツールを使用して、シンプルな Node.js API に対して負荷テストを行います。
前提条件
このチュートリアルを進めるには、いくつかの準備が必要です。
- JavaScript の基礎を理解する
- Node.js (バージョン 10.3 以上) をローカル システムにインストールする
- Heroku アカウントを用意する
- CircleCI アカウントを用意する
- GitHub アカウントを用意する
これらのインストールとセットアップが済んだら、チュートリアルを始めましょう。
ホスティング用の Heroku アプリをセットアップする
まず、API をホストするための Heroku アプリケーションをセットアップします。 Heroku アプリ ダッシュボードに移動して、 [New (新規)]、[Create new app (新規アプリを作成)] の順にクリックします。 任意の名前を使用して、新規アプリを作成します。
指定したアプリ名 (上図では node-loadtest
) をメモします。 この情報は、このチュートリアルで後ほど必要になります。
次に、ダッシュボードの [Account Settings
(アカウント設定)] セクションで Heroku API キーを確認します。
この情報もチュートリアルで後ほど必要になります。
テスト プロジェクトをクローンする
次に、チュートリアル用の API プロジェクトをクローンします。 この API プロジェクトはシンプルな Node.js API アプリケーションであり、ルート エンドポイント 1 つと、ユーザーのコレクションをフェッチするためのエンドポイント 1 つで構成されています。 以下のコマンドを実行して、プロジェクトをクローンします。
git clone --single-branch --branch base-project https://github.com/coderonfleek/node-loadtest
クローンが完了したら、以下のコマンドを実行して、プロジェクトのルートに移動し依存関係をインストールします。
cd node-loadtest
npm install
インストールが完了したら、以下のコマンドでアプリケーションを実行します。
npm start
アプリケーションがデフォルト ポート 3000
でのリッスンを開始します。 Postman を開き、http://localhost:3000/users/get
エンドポイントに対して GET
リクエストを行ってみましょう。 ユーザーの配列が返されれば成功です。
上図のような結果が得られれば、 API は正常に機能しています。
CircleCI に接続する
CircleCI で API プロジェクトをセットアップするために、まず、プロジェクトを GitHub にプッシュする必要があります。
次に、CircleCI ダッシュボードの [Projects (プロジェクト)] ページに移動し、(適切な GitHub アカウントを選択して) プロジェクトを追加します。
[Set Up Project (プロジェクトをセットアップ)] ボタンをクリックして、設定を始めましょう。 下図の画面が開きます。
セットアップ ページで、表示されたサンプルを無視して設定ファイルを手動で追加するため、[Use Existing Config (既存の設定ファイルを使用する)] をクリックします。 パイプラインの設定ファイルをダウンロードするのか、ビルドを開始するのかを確認するメッセージが表示されます。
[Start Building (ビルドの開始)] をクリックします。 設定ファイルのセットアップがまだのため、このビルドは失敗します。 このセットアップ作業は後ほど行います。
最後に、先ほど追加したプロジェクトの環境変数を設定します。 これにより、デプロイ用 Heroku アプリケーションへの認証済みアクセスが可能になります。
パイプライン ページで [Project Settings (プロジェクト設定)] ボタンをクリックして、プロジェクト設定に移動します。 このチュートリアルのプロジェクトが選択されていることを確認してください。
プロジェクト設定ページのサイド メニューにある [Environment Variables (環境変数)] をクリックします。
環境変数のページで、[Add Environment Variable (環境変数を追加)] をクリックします。
以下の環境変数を追加します。
HEROKU_APP_NAME
: Heroku アプリケーションの名前 (今回はcci-node-loadtest
)HEROKU_API_KEY
: Heroku アカウントの API キー (前述)
これで、Heroku にデプロイするための CircleCI コンソールでのセットアップはすべて完了です。
パイプライン設定ファイルに負荷テストを追加する
いよいよ、デプロイ パイプラインをビルドします。パイプラインでは、デプロイのたびに、API の /users/get
エンドポイントの負荷テストを行います。 プロジェクトのルートに、.circleci
という名前のフォルダーを作成して、config.yml
という名前のファイルをその中に作成します。 config.yml
に、以下のコードを入力します。
jobs:
build:
executor: heroku/default
steps:
- checkout
- heroku/install
- heroku/deploy-via-git
loadtestapi:
docker:
- image: circleci/node:10.16.3
steps:
- run:
name: 負荷テストの実行
command: |
sudo apt-get update
sudo apt-get install apache2-utils
ab -k -c 20 -n 250 https://$HEROKU_APP_NAME.herokuapp.com/users/get
orbs:
heroku: circleci/heroku@0.0.10
version: 2.1
workflows:
deploy:
jobs:
- build
- loadtestapi:
requires:
- build
ここで作成した設定ファイルには、次の 2 つのジョブが含まれています。
-
build
ジョブ: CircleCI の Heroku Orb を使用して、API プロジェクトを GitHub リポジトリからホスティング プラットフォーム上の Heroku アプリにデプロイします。 -
loadtestapi
ジョブ: API のデプロイ後、Apache Benchmark ツールをインストールし、ツールから250
件のリクエストを/users/get
エンドポイントに送信します。その際の同時実行数は20
で、持続的な接続を行うために-k
フラグでKeep-Alive
接続を指定しています。
API が正常にデプロイされるまで負荷テストが実行されないように、ワークフローを使用して、loadtestapi
ジョブの実行を build
ジョブの完了まで待機させています。
それでは、負荷テスト パイプラインを実行しましょう。 すべての変更をプロジェクトにコミットして、リモート GitHub リポジトリにプッシュします。 これで自動的にパイプラインがトリガーされ、ビルドが成功します。
ワークフローで loadtestapi
ジョブをクリックして、負荷テストの結果を確認します。
結果から、250
個のリクエストすべてが 0.44
秒以内に処理されたことがわかります。 これが望ましい結果かどうかは、みなさんそれぞれがアプリケーションに設定したパフォーマンス メトリクスによって異なります。 CircleCI では、他にもテスト実行に関するさまざまな詳細情報を確認できます。 これらの情報は、アプリケーション ユーザーの増加に合わせて、アプリケーション アーキテクチャを調整しスケーリングする際に役立ちます。
おわりに
大企業でもスタートアップ企業でも、ソフトウェアをユーザーに提供するのであれば、負荷テストはきわめて重要です。 負荷テストを行うことで、ユーザーの利用中にダウンタイムが発生する事態を回避できます。 このチュートリアルでは、API のデプロイ直後に、Web トラフィックの処理能力を確かめる負荷テストを実行する方法を学びました。 Apache Benchmark によるこのような負荷テストは、さまざまな方法で拡張できます。 他にも、負荷テスト プロセスに組み込める専用ツールや、Apache Benchmark の代わりに利用できる k6などのツールも存在します。
Happy coding!