前書き

この記事では、https://github.com/wg/wrk [wrk]と呼ばれるオープンソースのHTTPベンチマークツールに焦点を当てています。これは、高負荷*で HTTP *サービスの*レイテンシ*を測定します。

_Latency_は、リクエストが(wrkによって)行われた瞬間とレスポンスが(サービスから)受け取られた瞬間との間の時間間隔を指します。 これは、ブラウザまたはHTTPリクエストを送信する他の方法を使用して訪問したときに訪問者がサイトで経験する待ち時間をシミュレートするために使用できます。

wrkは、次のようなHTTPに依存するWebサイトまたはアプリケーションのテストに役立ちます。

  • Railsおよびその他のRubyアプリケーション

  • Expressおよびその他のJavaScriptアプリケーション

  • PHPアプリケーション

  • Webサーバーで実行されている静的Webサイト

  • Nginxのようなロードバランサーの背後にあるサイトおよびアプリケーション

  • キャッシングレイヤー

テストを*実際のユーザー*と比較することはできませんが、インフラストラクチャをより適切に計画できるように、予想される待機時間の優れた*推定*を提供する必要があります。 テストにより、パフォーマンスのボトルネックを把握することもできます。

wrkはオープンソースであり、https://github.com/wg/wrk [GitHub]で見つけることができます。

非常に安定しており、マルチスレッドの性質により、高負荷をシミュレートできます。 wrkの最大の機能は、http://www.lua.org/ [Lua]スクリプトを統合できることです。これにより、次のような多くの可能性が追加されます。

  • Cookieを使用したベンチマークリクエスト

  • カスタムレポート

  • 複数のURLのベンチマーク-人気のあるhttp://httpd.apache.org/docs/2.2/programs/ab.html [+ ab +](Apache HTTPサーバーベンチマークツール)ではできません

前提条件

このチュートリアルで使用するインフラストラクチャを次の図に示します。

image:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/wrk-application-overview.png [インフラストラクチャの概要]

ご覧のとおり、非常に単純なシナリオでwrkを使用します。 Node.jsアプリケーションでhttp://expressjs.com/[Express]のベンチマークを行います。

  • 2つのDroplet *をスピンアップします。1つは負荷を生成するwrk用で、もう1つはアプリケーション用です。 同じボックスにいた場合、リソースを奪い合い、結果は信頼できなくなります。

ベンチマークを実行するマシンは、ストレスのかかったシステムを処理するのに十分な強度を備えている必要がありますが、この場合、アプリケーションは非常に単純なので、同じサイズのマシンを使用します。

  • プライベートIPで通信するため、*同じ地域*で2つのドロップレットをスピンアップします

  • このチュートリアルを実行するには、1つのDroplet * wrk1 ともう1つの app1 *を呼び出します

  • * 2 GB *のメモリを選択します

  • * Ubuntu 14.04 *を選択します

  • [利用可能な設定]セクションで[プライベートネットワーク]を選択します

  • 各サーバーでhttps://www.digitalocean.com/community/tutorials/how-to-add-and-delete-users-on-an-ubuntu-14-04-vps[sudo user]を作成します

小さいドロップレットも機能しますが、テスト結果にはより長い遅延が予想されます。 実際のテスト環境では、アプリケーションサーバーは、運用環境で使用する予定のサイズと同じにする必要があります。

image:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/do-setup-infrastructure-with-notes.png [デジタル海洋インフラストラクチャ設定プレビュー]

ドロップレットの設定にヘルプが必要な場合は、https://www.digitalocean.com/community/tutorials/how-to-create-your-first-digitalocean-droplet-virtual-server [この記事]を参照してください。

ステップ1-両方のサーバー:Dockerをインストールする

生活を楽にするために、http://www.docker.com/ [Docker]を使用して、コンテナ内でwrkとアプリケーションを起動できるようにします。 これにより、Node.js環境、npmモジュール、debパッケージの設定をスキップできます。必要なのは、適切なコンテナをダウンロードして実行することだけです。 節約された時間は、学習の学習に費やされます。

Dockerに慣れていない場合は、https://www.digitalocean.com/community/tutorials/the-docker-ecosystem-an-introduction-to-common-components [こちら]でDockerの概要を読むことができます。

*注意:*このセクションのコマンドは、*両方のドロップレット*で実行する必要があります。

Dockerをインストールするには、サーバーにログインして次のコマンドを実行します。 まず、パッケージリストを更新します。

sudo apt-get update

WgetとcURLをインストールします。

sudo apt-get install -y wget curl

Dockerをダウンロードしてインストールします。

sudo wget -qO- https://get.docker.com/ | sh

ユーザーをsudoなしでDockerコマンドを実行できるように、ユーザーを `+ docker +`グループに追加します。

sudo gpasswd -a ${USER} docker
sudo service docker restart
newgrp docker

`+ docker +`が正しくインストールされていることを確認するには、次のコマンドを使用します。

docker --version

次のような出力が得られるはずです。

OutputDocker version 1.7.1, build 786b29d

ステップ2-テストアプリケーションの準備

  • app1 *ドロップレットでこれらのコマンドを実行します。

テストの目的で、著者はパブリックDockerレジストリにhttps://registry.hub.docker.com/u/czerasz/http-debugger/[Docker image]を公開しました。 Node.jsで記述されたHTTPデバッグアプリケーションが含まれています。 パフォーマンスビーストではありません(今日は記録を更新しません)が、テストとデバッグには十分です。 ソースコードhttps://github.com/czerasz/docker-http-debugger [こちら]をご覧ください。

もちろん、実際のシナリオでは、独自のアプリケーションをテストする必要があります。

アプリケーションを開始する前に、DropletのプライベートIPアドレスを `+ APP1_PRIVATE_IP +`という変数に保存します。

export APP1_PRIVATE_IP=$(sudo ifconfig eth1 | egrep -o "inet addr:[^ ]*" | awk -F ":" '{print $2}')

次の方法でプライベートIPを表示できます。

echo $APP1_PRIVATE_IP

出力:

Output

プライベートIPアドレスは異なるため、メモしてください。

digitalocean.comコントロールパネルからプライベートIPを取得することもできます。 ドロップレットを選択して、下の画像にある「設定」セクションに移動します。

image:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/do-get-private-ip-with-notes.png [デジタルオーシャンはDropletのプライベートIPを見つける]

次のコマンドを実行するだけで、アプリケーションを開始します。

docker run -d -p $APP1_PRIVATE_IP:3000:3000 --name=http-debugging-application czerasz/http-debugger

上記のコマンドは、最初に必要なDockerイメージをダウンロードしてから、Dockerコンテナーを実行します。 コンテナは_detached mode_で起動されます。これは単にバックグラウンドで実行されることを意味します。 オプション `+ -p $ APP1_PRIVATE_IP:3000:3000 `は、ポート ` 3000 `のローカルコンテナとポート ` 3000 +`のホストプライベートIP間のすべてのトラフィックをプロキシします。

次の図は、この状況を説明しています。

image:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/debugging-application-container-overview.png [アプリケーションコンテナの視覚化のデバッグ]

次に、 `+ curl +`でテストして、アプリケーションが実行されているかどうかを確認します。

curl -i -XPOST http://$APP1_PRIVATE_IP:3000/test -d 'test=true'

期待される出力:

OutputHTTP/1.1 200 OK
X-Powered-By: Express
X-Debug: true
Content-Type: text/html; charset=utf-8
Content-Length: 2
ETag: W/"2-79dcdd47"
Date: Wed, 13 May 2015 16:25:37 GMT
Connection: keep-alive

ok

アプリケーションは非常にシンプルで、 `+ ok `メッセージのみを返します。 したがって、wrkがこのアプリケーションを要求するたびに、小さな「 ok +」メッセージが返されます。

最も重要な部分は、アプリケーションログを分析することにより、wrkがアプリケーションに対して行った要求を確認できることです。

次のコマンドでアプリケーションログを表示します。

docker logs -f --tail=20 http-debugging-application

サンプル出力は次のようになります。

Output[2015-05-13 16:25:37] Request 1

POST/1.1 /test on :::3000

Headers:
- user-agent: curl/7.38.0
- host: 0.0.0.0:32769
- accept: */*
- content-length: 9
- content-type: application/x-www-form-urlencoded

No cookies

Body:
test=true

必要に応じて、ベンチマークテストの実行中にこれを実行したままにすることができます。 `+ CTRL-C +`でテールを終了します。

ステップ3-wrkのインストール

  • wrk1 *サーバーにログインし、wrkをインストールする準備をします。

Dockerがあるのでとても簡単です。 次のコマンドを使用して、Dockerレジストリハブからhttps://registry.hub.docker.com/u/williamyeh/wrk/ [+ williamyeh / wrk +]イメージをダウンロードするだけです。

docker pull williamyeh/wrk

上記のコマンドは、wrkを含むDockerイメージをダウンロードします。 wrkをビルドしたり、追加パッケージをインストールしたりする必要はありません。 (コンテナ内で)wrkを実行するには、この画像に基づいてコンテナを起動するだけで済みます。これはすぐに行います。

イメージは非常に小さく、3 MB未満であるため、ダウンロードには数秒しかかかりません。 お気に入りのLinuxディストリビューションにwrkを直接インストールする場合は、https://github.com/wg/wrk/wiki/Installing-Wrk-on-Linux [このwikiページ]にアクセスして、指示に従ってください。

また、このサーバーで変数「+ APP1_PRIVATE_IP +」を設定します。 * app1 *ドロップレットからのプライベートIPアドレスが必要です。

以下を使用して変数をエクスポートします。

export APP1_PRIVATE_IP=

「++」IPアドレスを* app1 * DropletのプライベートIPに変更することを忘れないでください。 この変数は現在のセッションでのみ保存されるため、次回ログインしてwrkを使用するときに忘れずに再設定してください。

ステップ4-wrkベンチマークテストを実行する

このセクションでは、最終的にwrkの動作を確認します。

このセクションのすべてのコマンドは、* wrk1 *ドロップレットで実行する必要があります。

wrkで利用可能なオプションを見てみましょう。 `+-version +`フラグだけでwrkコンテナを実行すると、その使用法の簡単な要約が出力されます:

docker run --rm williamyeh/wrk --version

出力:

Outputwrk 4.0.0 [epoll] Copyright (C) 2012 Will Glozer
Usage: wrk <options> <url>
 Options:
   -c, --connections <N>  Connections to keep open
   -d, --duration    <T>  Duration of test
   -t, --threads     <N>  Number of threads to use

   -s, --script      <S>  Load Lua script file
   -H, --header      <H>  Add header to request
       --latency          Print latency statistics
       --timeout     <T>  Socket/request timeout
   -v, --version          Print version details

 Numeric arguments may include a SI unit (1k, 1M, 1G)
 Time arguments may include a time unit (2s, 2m, 2h)

概要がわかりましたので、テストを実行するコマンドを作成しましょう。 このコマンドは、コンテナ内から実行していないため、まだ何も実行しないことに注意してください。

wrkで実行できる最も簡単なケースは次のとおりです。

wrk -t2 -c5 -d5s -H 'Host: example.com' --timeout 2s http://$APP1_PRIVATE_IP:3000/

つまり

  • + -t2 +:* 2 *個別の*スレッド*を使用

  • + -c5 +:* 6つの接続*を開きます(最初のクライアントはゼロです)

  • + -d5s +:* 5秒間*テストを実行します

  • + -H 'Host:example.com' +: `+ Host +`を渡す*ヘッダー*

  • +-timeout 2s +:* 2秒のタイムアウト*を定義する

  • `+ http:// $ APP1_PRIVATE_IP:3000 / `ターゲットアプリケーションは ` $ APP1_PRIVATE_IP:3000 +`でリッスンしています

  • アプリケーションの「+ / +」パスのベンチマーク

これは、ホームページを5秒間繰り返し要求する6人のユーザーとしても説明できます。

次の図は、この状況を示しています。

画像:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/wrk-architecture-structure.png [wrkアーキテクチャ構造]

テストの実際のコマンドは次のとおりです

説明したシナリオをwrk Dockerコンテナーで実行しましょう。

docker run --rm williamyeh/wrk -t2 -c5 -d5s -H 'Host: example.com' --timeout 2s http://$APP1_PRIVATE_IP:3000/

テストが実行されるまで数秒待って、結果を確認します。結果は次のステップで分析します。

ステップ5-出力を評価する

出力:

OutputRunning 5s test @ http://10.135.232.163:3000
 2 threads and 5 connections
 Thread Stats   Avg      Stdev     Max   +/- Stdev
   Latency     3.82ms    2.64ms  26.68ms   85.81%
   Req/Sec   550.90    202.40     0.98k    68.00%
 5494 requests in 5.01s, 1.05MB read
Requests/sec:   1096.54
Transfer/sec:    215.24KB
  • 現在の構成の概要:

    Running 5s test @ http://10.135.232.163:3000
     2 threads and 5 connections

    ここでは、ベンチマーク構成の簡単な概要を見ることができます。 ベンチマークには5秒かかり、ベンチマークされたマシンIPは「+10.135.232.163」であり、テストでは2つのスレッドを使用しました。

  • レイテンシおよびreq / sec統計の正規分布パラメーター:

    Thread Stats   Avg      Stdev     Max   +/- Stdev
     Latency     3.82ms    2.64ms  26.68ms   85.81%
     Req/Sec   550.90    202.40     0.98k    68.00%

    +このパートでは、ベンチマークの正規分布の詳細-https://en.wikipedia.org/wiki/Gaussian_function[Gaussian function]が持つパラメーターを示します。 +ベンチマークには常に正規分布があるとは限らないため、これらの結果は誤解を招く可能性があります。 したがって、常に* Max および + /-Stdev *の値を確認してください。 これらの値が高い場合、分布の裾が重い可能性があります。

  • リクエスト数、転送データ、およびスループットに関する統計:

     5494 requests in 5.01s, 1.05MB read
    Requests/sec:   1096.54
    Transfer/sec:    215.24KB

    ここでは、「 5.01+」秒の間にwrkが「5494」リクエストを行い、「+ 1.05MB 」のデータを転送できることがわかります。 単純な数学( `+リクエストの総数/ベンチマーク期間`)と組み合わせて、毎秒 ` 1096.54 +`リクエストの結果を取得します。

通常、設定するクライアントが多いほど、取得する1秒あたりのリクエスト数は少なくなります。 遅延も大きくなります。 これは、アプリケーションの負荷が大きくなるためです。

どのような結果が最適ですか?

あなたの目標は、 `+ Requests / sec `をできるだけ高く、 ` Latency +`をできるだけ低く保つことです。

理想的には、少なくともWebページについては、遅延が長すぎてはいけません。 アセットを使用したページの読み込み時間の制限は、約2秒以下のときに最適です。

今、あなたはおそらく自問するでしょう: `550.90 Requests / sec +`のレイテンシーは ` 3.82ms +`で良い結果ですか? 残念ながら、簡単な答えはありません。 次のような多くの要因に依存します。

  • 前に説明したように、クライアントの数

  • サーバーリソース-大きいインスタンスですか、小さいインスタンスですか?

  • アプリケーションを提供するマシンの数

  • サービスのタイプ-静的ファイルを提供するキャッシュですか、動的応答を提供する広告サーバーですか?

  • データベースの種類、データベースクラスターのサイズ、データベース接続の種類

  • リクエストとレスポンスのタイプ-それは小さなAJAXリクエストですか、それともファットAPIコールですか?

  • そして他の多くの

手順6-遅延を改善するためのアクションを実行する

サービスのパフォーマンスに満足できない場合、次のことができます。

  • サービスを調整します-コードを確認し、より効率的に実行できることを確認します

  • データベースをチェックして、それがあなたのボトルネックかどうかを確認します

  • 垂直にスケーリング-マシンにリソースを追加します

  • 水平スケール-サービスの別のインスタンスを追加し、ロードバランサーに追加します

  • キャッシングレイヤーを追加する

アプリケーションの改善の詳細については、https://www.digitalocean.com/community/tutorials/5-ways-to-improve-your-production-web-application-server-setup [5つの改善方法実稼働Webアプリケーションサーバーのセットアップ]。

サービスに変更を適用した後、サービスをベンチマークすることを忘れないでください。そうして初めて、サービスが改善されたことを確認できます。

それだけです、もしこのLuaがなかったら…

Luaスクリプトを使用して高度なHTTPリクエストをシミュレートする

wrkにはhttp://luajit.org/[LuaJIT](Lua用のJust-In-Timeコンパイラー)が組み込まれているため、Luaスクリプトで拡張できます。 導入部で述べたように、これにより多くの機能が追加されます。

wrkでLuaスクリプトを使用するのは簡単です。 ファイルパスを `+ -s +`フラグに追加するだけです。

Docker内でwrkを使用するため、最初にこのファイルをコンテナと共有する必要があります。 これは、Dockerの「+ -v +」オプションで実現できます。

仕事用のLuaスクリプトの一部

`+ test.lua +`というスクリプトを使用した一般的な形式では、コマンド全体は次のようになります。

docker run --rm -v `pwd`/scripts:/scripts williamyeh/wrk -c1 -t1 -d5s -s /scripts/test.lua http://$APP1_PRIVATE_IP:3000

前のステップでwrkコマンドとそのオプションについて説明しました。 このコマンドはそれ以上追加しません。スクリプトへのパスと、コンテナの外でDockerを見つける方法をDockerに指示するいくつかの追加コマンド。

`+-rm +`フラグは、コンテナが停止した後に自動的に削除します。

しかし、実際にLuaスクリプトを記述する方法を知っていますか? 恐れないでください。簡単に習得できます。 ここでは簡単な例を説明します。独自のより高度なスクリプトを実行できます。

最初に、wrkの内部ロジックを反映する事前に定義されたスクリプト構造について説明します。 次の図は、1つのスレッドの場合を示しています。

画像:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/lua-cycle.png [wrk Luaスクリプトサイクル]

wrkは、次の実行フェーズを実行します。

  • *解決*ドメインのIPアドレス

  • スレッド* setup *から始めます

  • *ストレステスト*フェーズを実行します。これは*実行*フェーズと呼ばれます

  • 最後のステップは単に*完了*と呼ばれます

複数のスレッドを使用する場合、1つの解決フェーズと1つの完了フェーズがありますが、2つのセットアップフェーズと2つの実行フェーズがあります。

image:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/lua-cycle-threads.png [2つのスレッドのwrk Luaスクリプトサイクル]

さらに、実行フェーズ*は、 init request 、および response *の3つのステップに分割できます。

image:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/lua-cycle-running-phase.png [wrk Luaスクリプトサイクル-実行フェーズ]

提示された図とhttps://github.com/wg/wrk/blob/master/SCRIPTING [ドキュメント]によれば、Luaスクリプト内で次のメソッドを使用できます。

  • + setup(thread)+:すべてのスレッドが初期化されたがまだ開始されていないときに実行されます。 スレッドにデータを渡すために使用

  • + init(args)+:各スレッドが初期化されるときに呼び出されます
    この関数は、スクリプトの追加のコマンドライン引数を受け取ります。これは、「-+」でwrk引数から分離する必要があります。 例:

wrk -c3 -d1s -t2 -s /scripts/debug.lua http://$APP1_PRIVATE_IP:3000 -- debug true
  • + request()+:各リクエストに対してHTTPオブジェクトを返す必要があります。 この関数では、メソッド、ヘッダー、パス、および本文を変更できます
    + `+ work.format`ヘルパー関数を使用して、リクエストオブジェクトを整形します。 例:

return wrk.format(method, path, headers, body)
  • + response(status、headers、body)+:応答が戻ったときに呼び出されます

  • + done(summary、latency、requests)+:すべてのリクエストが終了し、統計が計算されたときに実行されます
    この関数内では、次のプロパティが利用可能です:

Property

Description

summary.duration

run duration in microseconds

summary.requests

total completed requests

summary.bytes

total bytes received

summary.errors.connect

total socket connection errors

summary.errors.read

total socket read errors

summary.errors.write

total socket write errors

summary.errors.status

total HTTP status codes > 399

summary.errors.timeout

total request timeouts

latency.min

minimum latency value reached during test

latency.max

maximum latency value reached during test

latency.mean

average latency value reached during test

latency.stdev

latency standard deviation

latency:percentile(99.0)

99th percentile value

latency[i]

raw latency data of request i

各スレッドには独自のLuaコンテキストがあり、その中に独自のローカル変数があります。

ここで、いくつかの実用的な例を見ていきますが、wrkプロジェクトのhttps://github.com/wg/wrk/tree/master/scripts [`+ scripts +`ディレクトリ]でさらに多くの便利なベンチマークスクリプトを見つけることができます。

例: `+ POST +`リクエスト

`+ POST`リクエストをシミュレートする最も簡単な例から始めましょう。

`+ POST`リクエストは通常​​、サーバーにデータを送信するために使用されます。 これはベンチマークに使用できます:

  • HTMLフォームハンドラー:HTMLフォームの `+ action +`属性にあるアドレスを使用します。

    <form action="/login.php">
    ...
    </form>
  • + POST + APIエンドポイント:安らかなAPIがある場合は、記事を作成するエンドポイントを使用します。

    POST /articles
  • wrk1 *ドロップレットに `+ scripts / post.lua +`ファイルを作成することから始めます。

cd ~
mkdir scripts
nano scripts/post.lua

次のコンテンツを追加します。

post.lua

wrk.method = "POST"
wrk.body   = "login=sammy&password=test"
wrk.headers["Content-Type"] = "application/x-www-form-urlencoded"

このスクリプトは非常にシンプルであり、前述の方法はまだ使用していません。 グローバルな `+ wrk +`オブジェクトプロパティを変更しました。

リクエストメソッドを `+ POST `に変更し、ログインパラメーターを追加し、HTMLフォームが使用するMIMEタイプに ` Content-Type +`ヘッダーを指定しました。

ベンチマークを開始する前に、スクリプト、Dockerコンテナー、およびアプリサーバーの関係を視覚化するのに役立つ図を次に示します。

image:https://assets.digitalocean.com/articles/wrk-ubuntu14.04/container-overview.png [Dockerコンテナの視覚化]

真実の瞬間-このコマンドでアプリケーションのベンチマークを実行します(* wrk1 *ドロップレットで実行):

docker run --rm -v `pwd`/scripts:/scripts williamyeh/wrk -c1 -t1 -d5s -s /scripts/post.lua http://$APP1_PRIVATE_IP:3000

出力:

OutputRunning 5s test @ http://10.135.232.163:3000
 1 threads and 1 connections
 Thread Stats   Avg      Stdev     Max   +/- Stdev
   Latency     1.04ms  718.38us  12.28ms   90.99%
   Req/Sec     1.02k   271.31     1.52k    66.00%
 5058 requests in 5.00s, 0.97MB read
Requests/sec:   1011.50
Transfer/sec:    198.55KB

出力は、前に見たものに似ています。

ここでは、1つの接続のみでベンチマークを行っていることに注意してください。 これは、1人のユーザーのみが継続的にログインし、ユーザー名とパスワードを渡したいという状況に対応します。 これは、CSS、画像、またはJavaScriptファイルを要求していません。

より現実的なシナリオでは、クライアントとスレッドの数を増やし、同時に遅延パラメーターを観察して、アプリケーションがユーザーの資格情報を検証できる速度を確認する必要があります。

例:複数のURLパス

別の一般的なニーズは、アプリケーションの複数のパスを同時にテストすることです。

`+ data `ディレクトリに ` paths.txt +`というファイルを作成し、ベンチマークで使用するすべてのパスを追加しましょう。

cd ~
mkdir data
nano data/paths.txt

以下の `+ data / paths.txt +`の例を見つけます。

path.txt

/feed.xml
/contact/
/about/
/blog/
/2015/04/21/nginx-maintenance-mode/
/2015/01/06/vagrant-workflows/
/2014/12/10/top-vagrant-plugins/

次に、https://gist.github.com/anonymous/91dc4d8a752d7916d48c [this simple script]を取得し、「+ scripts / multiple-url-paths.lua +」として保存します。

multiple-url-paths.lua

-- Load URL paths from the file
function load_url_paths_from_file(file)
 lines = {}

 -- Check if the file exists
 -- Resource: http://stackoverflow.com/a/4991602/325852
 local f=io.open(file,"r")
 if f~=nil then
   io.close(f)
 else
   -- Return the empty array
   return lines
 end

 -- If the file exists loop through all its lines
 -- and add them into the lines array
 for line in io.lines(file) do
   if not (line == '') then
     lines[#lines + 1] = line
   end
 end

 return lines
end

-- Load URL paths from file
paths = load_url_paths_from_file("/data/paths.txt")

print("multiplepaths: Found " .. #paths .. " paths")

-- Initialize the paths array iterator
counter = 0

request = function()
 -- Get the next paths array element
 url_path = paths[counter]

 counter = counter + 1

 -- If the counter is longer than the paths array length then reset it
 if counter > #paths then
   counter = 0
 end

 -- Return the request object with the current URL path
 return wrk.format(nil, url_path)
end

このチュートリアルではLuaスクリプトの詳細を説明しようとはしていませんが、スクリプト内のコメントを読むと、Luaスクリプトの機能を理解できます。

`+ multiple-url-paths.lua `スクリプトは ` / data / paths.txt `ファイルを開き、このファイルにパスが含まれている場合、それらは内部の ` paths +`配列に保存されます。 次に、リクエストごとに次のパスが取られます。

このベンチマークを実行するには、次のコマンドを使用します(* wrk1 *ドロップレットで実行)。 コピーしやすくするために改行が追加されていることに気付くでしょう。

docker run --rm \
          -v `pwd`/scripts:/scripts \
          -v `pwd`/data:/data \
          williamyeh/wrk -c1 -t1 -d5s -s /scripts/multiple-url-paths.lua http://$APP1_PRIVATE_IP:3000

出力:

Outputmultiplepaths: Found 7 paths
multiplepaths: Found 7 paths
Running 5s test @ http://10.135.232.163:3000
 1 threads and 1 connections
 Thread Stats   Avg      Stdev     Max   +/- Stdev
   Latency     0.92ms  466.59us   4.85ms   86.25%
   Req/Sec     1.10k   204.08     1.45k    62.00%
 5458 requests in 5.00s, 1.05MB read
Requests/sec:   1091.11
Transfer/sec:    214.17KB

JSONおよびYAMLを使用した事前リクエスト

今、あなたは他のベンチマークツールもこれらのタイプのテストを行うことができると思うかもしれません。 ただし、wrkには、JSONまたはYAML形式を使用して高度なHTTP要求を処理する機能もあります。

たとえば、各リクエストを詳細に説明するJSONまたはYAMLファイルをロードできます。

著者は、http://czerasz.com/2015/07/19/wrk-http-benchmarking-tool-example/ [著者の技術ブログ]にJSONリクエストを含む高度な例を公開しています。

wrkとLuaを使用して、考えられるあらゆる種類のHTTP要求をベンチマークできます。

結論

この記事を読んだ後、wrkを使用してアプリケーションのベンチマークを行うことができるはずです。 補足として、Dockerの美しさ、およびアプリケーションの設定とテスト環境を大幅に最小化する方法も確認できます。

最後に、wrkを使用したLuaスクリプトを使用して、高度なHTTPリクエストを実行できます。