Webサーバー向けのベンチマークツールを使ってみよう(前編)――Apache BenchとSiege
WebサーバーやWebサービスの公開前には、そのサーバーがどの程度のアクセスにまで耐えられるかを事前に調査しておくことが好ましい。本記事では、こういった調査の際によく使われる「Apache Bench」および「Siege」というツールの使い方を紹介する。
目次
サービスの公開前に行っておくべき負荷テスト
昨今では低価格サーバーでも高性能化が進んでおり、静的なページを表示するだけのWebサーバーや比較的負荷の少ない処理を行うようなWebアプリケーションでは、1台のサーバーのみでそれなりの規模のアクセスに耐えられるようになっている。とはいえ、CPUの性能やメモリ容量、ストレージの種類などによってアプリケーションのピーク性能は変動するため、単純にハードウェアの性能や使用するソフトウェアといった情報だけでどの程度までのアクセスを捌けるのかを判断することは難しい。実際、負荷をかけてみたら「想定していたレベル」よりもスループットが低かった、という例は少なくない。そのため、あらかじめサーバーに対して負荷テストを行い、想定している最大アクセスに耐えられるかどうかを調査しておくことが重要となる。
こういった負荷テストの手法や、それを実現するためのツールにはさまざまなものがあるが、本記事ではそのなかでも使いやすく汎用性も高い「Apache Bench」と「Siege」、そして複雑なテストケースにも対応できる「Apache Jmeter」、JavaScriptの実行タイムまでも計測できる「wbench」について、2回に渡って紹介する(図1)。
手軽に利用できるベンチマークツール「Apache Bench」
まず紹介するのは、手軽なベンチマークツールとして広く利用されているコマンドラインツール「Apache Bench」(ab)だ。Apache BenchはApache HTTP Serverに同梱されているため、Apache HTTP Serverが利用できる環境であればほとんどの場合ですぐに利用できる。Apache HTTP Serverに付属するツールではあるが、Webサーバーにリクエストを送信してその結果を集計するというシンプルなツールであるため、Apache HTTP Server以外のWebサーバーもテスト可能だ。
Apache Benchで実行できるテストは非常にシンプルで、指定したURLに対し高い頻度で連続アクセスを行う、というだけだ。対象とできるURLは1つだけなので複雑な遷移などはチェックできないが、サイトのトップページなどアクセスが多いと思われるページや、負荷の高いと思われるページがどれだけのアクセスに耐えられるかを調べるといった用途で利用できる。
Apache Benchの基本的な使い方
Apache Benchは「ab」というコマンドとして提供される。通常は「-c」や「-n」オプションを使い、URLとともに同時に発生させるリクエスト数、総リクエスト数などを指定して実行する。
ab -c <同時リクエスト数> -n <総リクエスト数> <URL>
「同時リクエスト数」は、同時に接続を行うクライアントの数に相当する。たとえば「http://localhost/」というURLに対し同時に10リクエストを発生させ、トータルで10000リクエストを行う場合のオプションとその実行結果は次のようになる。この場合、各クライアントはそれぞれ1000リクエストを送信することになる。また、ここではベンチマーク対象とするマシン上でApache Benchを実行している。
$ ab -c 10 -n 10000 http://localhost/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Apache/1.3.42 Server Hostname: localhost Server Port: 80 Document Path: / Document Length: 111114 bytes Concurrency Level: 10 Time taken for tests: 11.054 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 1114673762 bytes HTML transferred: 1111140000 bytes Requests per second: 904.68 [#/sec] (mean) Time per request: 11.054 [ms] (mean) Time per request: 1.105 [ms] (mean, across all concurrent requests) Transfer rate: 98479.32 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.0 0 1 Processing: 3 11 6.0 9 72 Waiting: 2 8 5.3 6 65 Total: 4 11 6.0 9 72 Percentage of the requests served within a certain time (ms) 50% 9 66% 12 75% 13 80% 14 90% 18 95% 23 98% 28 99% 33 100% 72 (longest request)
この結果からは、1リクエストの処理にかかった時間は4~72ミリ秒(ms)でその平均は11.054ミリ秒、転送レートは毎秒98479.32KBであることが分かる。
また、Webサーバーのスループットは同時接続数が増えるほど低下するのが一般的だ。たとえば次の例のように同時接続数を100に増やした場合、1リクエストの処理にかかった時間は平均121.709ミリ秒に増加しており、スループットは毎秒89439.06KBに低下していることが分かる。
$ ab -c 100 -n 10000 http://localhost/ This is ApacheBench, Version 2.3 <$Revision: 1706008 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking localhost (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Apache/1.3.42 Server Hostname: localhost Server Port: 80 Document Path: / Document Length: 111114 bytes Concurrency Level: 100 Time taken for tests: 12.171 seconds Complete requests: 10000 Failed requests: 0 Total transferred: 1114674883 bytes HTML transferred: 1111140000 bytes Requests per second: 821.64 [#/sec] (mean) Time per request: 121.709 [ms] (mean) Time per request: 1.217 [ms] (mean, across all concurrent requests) Transfer rate: 89439.06 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.5 0 7 Processing: 5 121 25.3 114 287 Waiting: 3 118 25.2 110 283 Total: 12 121 25.1 114 287 Percentage of the requests served within a certain time (ms) 50% 114 66% 128 75% 138 80% 143 90% 156 95% 166 98% 180 99% 193 100% 287 (longest request)
なお、これはApache Benchに限らない話ではあるが、こういったベンチマークツールはそのツールを実行しているマシンの性能や、ツールを実行しているマシンとベンチマーク対象との間のネットワーク環境によって結果が変わってくる。そのため、サーバーソフトウェアが稼動しているマシン上で実行するだけでなく、同じネットワーク内の別のマシン上で実行したり、インターネット経由で実行したりと、環境を変えて試すことをおすすめする。
たとえば次の例は、インターネット経由で先ほどと同じサーバーに対してベンチマークテストを行ったものだ。この場合、1リクエスト辺りの平均処理時間は1009.492ミリ秒で、スループットは毎秒10783.08KB(約86Mbps)と大きく低下している。これは、テストで発生したトラフィックが使用したサーバーのインターネット接続回線帯域幅上限である100Mbps(「さくらの専用サーバ」標準の100Mbpsベストエフォート回線)に近づいたためと思われる。
$ ab -c 100 -n 10000 http://example.com/ This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking example.com (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Apache/1.3.42 Server Hostname: example.com Server Port: 80 Document Path: / Document Length: 111114 bytes Concurrency Level: 100 Time taken for tests: 100.949 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 1114667835 bytes HTML transferred: 1111140000 bytes Requests per second: 99.06 [#/sec] (mean) Time per request: 1009.492 [ms] (mean) Time per request: 10.095 [ms] (mean, across all concurrent requests) Transfer rate: 10783.08 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 26 79 155.2 56 3086 Processing: 137 922 156.1 889 2359 Waiting: 52 502 154.0 481 2108 Total: 166 1002 216.3 947 4105 Percentage of the requests served within a certain time (ms) 50% 947 66% 982 75% 1014 80% 1042 90% 1151 95% 1348 98% 1906 99% 1995
1Gbpsのローカルネットワークで接続されている別のマシンからベンチマークを実行した場合は次のようにスループットが毎秒82679.93KB(約661Mbps)となっていることから、上記のケースではネットワーク帯域がボトルネックになっていることが分かる。なお、ここではローカルネットワーク経由で接続を行わせるためIPアドレスで対象サーバーを指定し、送信するHTTPヘッダを追加する「-H」オプション(後述)で「Host:」ヘッダーを送信するよう指定している。
$ ab -c 100 -n 10000 -H "Host: example.com" http://192.168.1.100/ This is ApacheBench, Version 2.3 <$Revision: 1430300 $> Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/ Licensed to The Apache Software Foundation, http://www.apache.org/ Benchmarking 192.168.1.100 (be patient) Completed 1000 requests Completed 2000 requests Completed 3000 requests Completed 4000 requests Completed 5000 requests Completed 6000 requests Completed 7000 requests Completed 8000 requests Completed 9000 requests Completed 10000 requests Finished 10000 requests Server Software: Apache/1.3.42 Server Hostname: 192.168.1.100 Server Port: 80 Document Path: / Document Length: 111114 bytes Concurrency Level: 100 Time taken for tests: 13.166 seconds Complete requests: 10000 Failed requests: 0 Write errors: 0 Total transferred: 1114671913 bytes HTML transferred: 1111140000 bytes Requests per second: 759.54 [#/sec] (mean) Time per request: 131.658 [ms] (mean) Time per request: 1.317 [ms] (mean, across all concurrent requests) Transfer rate: 82679.93 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 1 10.1 1 1004 Processing: 10 129 37.3 125 743 Waiting: 7 115 31.6 110 739 Total: 11 130 38.3 126 1085 Percentage of the requests served within a certain time (ms) 50% 126 66% 138 75% 146 80% 152 90% 164 95% 174 98% 215 99% 312 100% 1085 (longest request)
Apache Benchの主要オプション
テストサーバーや一般には公開していないサーバーなどの場合、Basic認証などのアクセス制限を設定している場合がある。こういったアクセス制限がかけられているサーバーやURLに対するテストを行う場合は、abコマンドのコマンドラインオプションで認証用のIDを指定してやれば良い。
たとえばBasic認証での認証が必要なサーバーの場合、次のように「-A」オプションで認証情報を指定できる。
-A <ユーザー名>:<パスワード>
また、「-H」オプションで送信するHTTPヘッダを追加できる。たとえば「Host: example.com」というHTTPヘッダを送信したい場合、次のように指定する。
-H "Host: example.com"
Cookieを使ってログイン情報を保持しているような場合は、Cookie情報を送信するようコマンドラインオプションで指定する。送信するCookie情報は、ログインした状態でWebブラウザでそのサイトにアクセスし、開発者用ツールなどで確認する。たとえばGoogle Chromeの場合、「デベロッパーツール」の「Network」タブでホストに送信しているHTTPヘッダを表示できるので、そこで「Cookie:」ヘッダの情報を確認する(図2)。
この例の場合、ホストには複数のCookieが送信されていたが、ログインに必要なのは「user=27448::kQp18UjdStmPdplkFadpVs」というCookieだ。この情報を「-C」オプションで指定する。-Cオプションでは、引数として「<キー>:<値>」という形でCookieの値を指定する。この例の場合は次のように指定する。
-C user:27448::kQp18UjdStmPdplkFadpVs
もしくは、-Hオプションを使って「Cookie:」ヘッダを追加しても同様の結果が得られる。
-H "Cookie: user=27448::kQp18UjdStmPdplkFadpVs;"
複数のURLを対象に負荷テストを行える「Siege」
続いて紹介するのは、「Siege」という負荷テストツールだ。こちらもコマンドラインで操作するツールで、オープンソースソフトウェアとして提供されている。ライセンスはGPLv3だ。
SiegeはApache Benchと同様、指定したURLに対して連続してアクセスし、その結果を集計して表示するツールだが、特徴として「複数のURLを指定してそれぞれに順番にアクセスする」といったテストを実行できる点がある。また「指定した複数のURLからランダムにURLを選んでアクセスする」というテストも行える。これによって、サーバーに対し実際の運用環境に近い負荷をかけることができる。
SiegeはDebianやUbuntuでは公式パッケージとして提供されており、apt-getコマンド等でインストールできる。
# apt-get install siege
また、Red Hat Enterprise Linux 7やCentOS 7では拡張パッケージ集であるEPELリポジトリでsiegeパッケージが提供されており、こちらのリポジトリを利用してインストールが可能だ。
Siegeの基本的な使い方
Siegeではさまざまな方法でテスト対象となるURLを指定できる。もっともシンプルなのは、siegeコマンドの引数としてURLを指定する方法だ。たとえば「http://example.com/」というURLに対しテストを行うには、以下のようにする。
$ siege http://example.com/ ** SIEGE 3.0.8 ** Preparing 15 concurrent users for battle. The server is now under siege...^C ←Ctrl+Cキーを押下する Lifting the server siege... done. Transactions: 179 hits Availability: 100.00 % Elapsed time: 6.79 secs Data transferred: 5.48 MB Response time: 0.07 secs Transaction rate: 26.36 trans/sec Throughput: 0.81 MB/sec Concurrency: 1.78 Successful transactions: 179 Failed transactions: 0 Longest transaction: 0.29 Shortest transaction: 0.01 FILE: /var/log/siege.log You can disable this annoying message by editing the .siegerc file in your home directory; change the directive 'show-logfile' to false. [error] unable to create log file: /var/log/siege.log: Permission denied
siegeコマンドのデフォルト設定ではテスト時間が設定されておらず、自動ではテストが終了されない。そのため、適当なタイミングでCtrl+Cキーを入力してテストを手動で終了させる必要がある。
テストを終了させると、それまでのリクエスト結果が出力される。この例では毎秒26.36個のリクエストを処理でき、その処理時間は0.01~0.29秒ということが分かる。なお、Siegeではログをファイルに出力する機能があるが、デフォルトではその保存先が一般ユーザーには書き込み権限が与えられていない「/var/log/siege.log」となっているためログの出力に失敗している。
上記の例では手動でテストを終了させていたが、テスト時間を指定してその時間が過ぎたら自動でテストを終了させることも可能だ。テスト時間は、「-t」オプションで指定できる。
-t <時間>[単位]
単位は「M」もしくは「m」(分)、「S」「s」(秒)、「H」「h」(時間)が指定可能だ。単位を指定しなかった場合、「m」が指定されたものとして扱われる。
また、siegeコマンドのデフォルト設定では同時接続数が15となっているが、これは「-c」オプションで変更できる。
-c <同時接続数>
複数のURLを対象にテストを行う
複数のURLを対象にテストを行うには、まずテストするURLを記述したテキストファイルを用意する。このファイルには次のように1行に1つずつのURLを記入する。
http://example.com/ http://example.com/story/16/01/16/0015218 http://example.com/story/15/12/28/035242 http://example.com/story/16/01/28/0437240/ http://example.com/~hylom/journal http://example.com/journals http://example.com/story/15/12/15/0646203 http://example.com/story/15/07/17/1855258 http://example.com/story/12/07/19/0814221
続いて、「-f」オプションでこのファイルを指定してsiegeコマンドを実行する。たとえば「urls.txt」というファイルにURLを記入した場合、以下のようになる。
$ siege -f urls.txt
この場合、指定したファイル中のURLに対し先頭から順にアクセスが行われる。先頭から末尾まですべてのURLにアクセスしたら、また先頭のURLに戻ってリクエストが続けられる。
POSTでのアクセスを行う
URLを指定する場合、「POST」というキーワードを付けることで、POSTリクエストを行うよう指定できる。また、送信するデータはGETリクエストにおけるクエリ文字列と同様の形で指定が可能だ。ここで指定したデータは「application/x-www-form-urlencoded」形式で送信される。
<URL> POST <キー1>=<値>&<キー2>=<値>&...
たとえば次のように指定することで、「http://example.com/login」というURLに対しPOSTでログイン情報を送信できる。もちろんサイトによって送信すべきパラメータは異なるので、実際に試す場合はそれに応じたデータを送信してほしい。
http://example.com/login POST userlogin=login&nickname=hylom&passwd=password
siegeコマンドでは「-g」オプションを指定することで、送受信されるHTTPヘッダを表示できる。これを利用し、テストを実行する前に指定したURLやPOSTデータが正しいかどうかを確認できる。
$ siege -g "http://example.com/login POST userlogin=login&nickname=hylom&passwd=password" POST /login HTTP/1.0 Host: example.com Accept: */* User-Agent: Mozilla/5.0 (pc-x86_64-linux-gnu) Siege/3.0.8 Connection: close Content-type: application/x-www-form-urlencoded Content-length: 46 userlogin=login&nickname=hylom&passwd=password HTTP/1.1 302 Found Date: Tue, 13 Dec 2016 11:02:33 GMT Location: / Server: Mojolicious (Perl) Connection: close Set-Cookie: mojolicious=eyJleHBpcmVzIjoxNDgxNjMwNTUzLCJzZXNzaW9uIjp7InRva2VuIjoidXRXWVdYM2tPWkFxSjBOR2tsNzloR0FhRXdiUTBoQk9zN3ZNeEdVVk9KWUxFQ2ZuNW5zS3lMbHNCWVNtenBSdThBMFV0dVY4MVNwbVxuSmVRT1hJenNKQ2N1RTFHMUNxRlpkZDFuMHFhQSt6Nk9UTGtzMDJpY3Y0WWE3ZVp6OUR3azIvTG1kK3ZtSzFvbnM1SmFvUDFNbWZVN1xuZXo5cXhrK01ZVEZZNkRSYm1rdz1cbiIsInRpbWVzdGFtcCI6MTQ4MTYyNjk1MywicmVtb3RlX2FkZHIiOm51bGx9fQ----83bbb5e6df72f9f35ae1dd321cf5386c541ce5cf; expires=Tue, 13 Dec 2016 12:02:33 GMT; path=/; HttpOnly Content-Length: 0 : :
Siegeでのテスト例
Siegeでは指定したファイルに記載された先頭のURLから順にリクエストを発生させるので、これを利用して「サイトにログインしてあるアクセスを行いログアウトする」というようなユースケースを再現した負荷テストを行うことが可能だ。たとえば次の設定ファイルは、まずサイトにアクセスしたらログインし、ログインした状態で複数のURLにアクセスし、最後にログアウトする、という利用ケースを模したものだ。
http://example.com/ ←サイトのトップページにアクセス http://example.com/login ←ログインページにアクセス http://example.com/login POST userlogin=login&nickname=hylom&passwd=passwd ←ログイン http://example.com/story/16/01/16/0015218 以下、適当なアクセス : : http://example.com/logout ←ログアウト
また、-fオプションでアクセスするURLが記載されたテキストファイルを指定した場合、これに加えて「-i」オプションを指定することで、テキストファイルに記載されたURLをランダムに選んでアクセスするようなテストパターンを実行できる。これによって、実環境により近いようなアクセスパターンで負荷テストを実行することもできる。
認証が必要なサイトやページを対象にテストを行う
Siegeでは設定ファイルを用意することで、より詳しくその挙動をカスタマイズできる。設定ファイルはsiegeコマンドとともにインストールされる「siege.config」コマンドを実行することで作成できる。
$ siege.config New configuration template added to /home/hylom/.siegerc Run siege -C to view the current settings in that file
このコマンドを実行すると、ユーザーのホームディレクトリに「.siegerc」という設定ファイルが作成されるので、このファイルをテキストエディタなどで編集する。設定ファイル中には多数の設定項目が用意されているが、たとえばBasic認証で使用するユーザー名やパスワードの設定は「login」というパラメータで指定できる。
login = <ユーザー名>:<パスワード> login = <ユーザー名>:<パスワード>:<realm>
この設定は複数の記入が可能だ。また、「realm」では、Basic認証が必要なページにアクセスした際にサーバーから送られるrealm文字列を指定する。サーバーから送られたrealm文字列がここで指定した文字列と一致した場合に、指定したユーザー名およびパスワードで認証が行われるようになる。realmを省略した場合はすべてのBasic認証が対象となる。
また、「login-url」パラメータではテストの実行前にアクセするURLを指定できる。
login-url = <URL>
このパラメータが指定されていた場合、Siegeはテストの実行時にまずこのURLにアクセスしてから他のURLにアクセスを行うようになる。通常、このURLにはログインを行うためのURLなどを指定することになる。ログインにPOSTアクセスが必要な場合は、前述の「POST」キーワードを使って次の例のようにURLを指定する。
login-url = http://example.com/login POST userlogin=login&nickname=hylom&passwd=passwd
そのほか設定ファイルではログの保存先や同時接続数、「keep-alive」接続を利用するかどうか、使用するプロクシなどさまざまな設定が可能だ。siege.configファイルで生成した設定ファイルではファイル中に各設定項目とその説明がコメントとして含まれているので、詳しくはそれらを参照して欲しい。
テストツールはネットワーク環境や用法を守って正しく利用しよう
Apache BenchやSiegeでは、コマンドラインで手軽に大量のアクセスを発生させることができる手軽さが便利なツールだ。そのため、単にWebサーバーの性能が要件を満たしているかを確認する以外に、チューニングやハードウェア構成の変更といった作業の効果を確認するためにも利用できる。サービス運用開始後にトラフィックに耐えられなくなるといったトラブルを回避するためにも、こういったツールを活用してサービスの性能を確認しておくと良いだろう。
なお、Apache BenchやSiegeに限らないが、こういった負荷テストツールは使い方を間違えたり、悪用したりするとサーバーに過大な負荷を与えることも可能で、それによって最悪サーバーやネットワークをダウンさせてしまう可能性もある。そのため、実運用されているサーバーや、第三者のサーバーなどに対しては不用意に実行しないよう注意したい。また、ホスティングサービスやクラウドなど第三者が管理しているインフラを利用している場合、負荷テストが攻撃だと誤認識される可能性もある点にも気を付けたい。