h2load, apache benchによる負荷テスト
前回の記事で触れたApache JMeterやGatlingとは違って、今回試したのはシナリオとかもなくHTTPのリクエストを大量に投げて、スループットやレイテンシを計測してみたい時に便利なツール。
実際に試したのは次の2つ。他にも、wrkやvmbench、siegeが気になったので試したらまた追記。
h2load
- Installation: HTTP/2 に対応するベンチマークツール h2load を Build するメモ | ぶっちろぐ
- http/2に対応
Command:
$ h2load -n 1000 -c 200 --h1 http://example.com/test.jpg
-n
: 総リクエスト数-c
: 並行リクエスト数--h1
: HTTP/1.1を使用
ab: apache bench
- Installation: Apacheを入れたら、一緒に入ります (
# yum install httpd
)。 -t
オプションがあって、時間指定ができる。
Command:
基本的には、h2loadと同じような
$ ab -n 1000 -c 200 http://example.com/test.jpg
並列 200で10秒間リクエストを送る
$ ab -t 10 -c 200 http://example.com/test.jpg
Sanicのベンチマークを試す
refs: GitHub - channelcat/sanic: Python 3.5+ web server that's written to go fast
Sanicというuvloopを使ったPythonのWebサーバ・フレームワークは、wrkを使ってベンチマークをとっています。試しにh2loadやabでも大体同じようなスループット、レイテンシになるのか試してみた。 全部試すのは大変なので、Sanicの負荷計測をしてみます。
環境は、sanicのREADMEに合わせて
$ sudo apt-get update && sudo apt-get upgrade $ sudo apt-get install python3-venv $ python3 -m venv venv $ source venv/bin/activate (venv) $ which pip /home/ubuntu/venv/bin/pip
tornadoの負荷テスト
用意したtornadoのコードはこちらです。
import tornado.ioloop import tornado.web import json class MainHandler(tornado.web.RequestHandler): def get(self): self.write(json.dumps({"hello": "world"})) def make_app(): return tornado.web.Application([ (r"/", MainHandler), ]) if __name__ == "__main__": app = make_app() app.listen(8080) tornado.ioloop.IOLoop.current().start()
h2loadの結果
$ h2load -n 5000 -c 100 --h1 http://ec2-hoge.ap-northeast-1.compute.amazonaws.c om/ starting benchmark... spawning thread #0: 100 total client(s). 5000 total requests Application protocol: http/1.1 progress: 10% done progress: 20% done progress: 30% done progress: 40% done progress: 50% done progress: 60% done progress: 70% done progress: 80% done progress: 90% done progress: 100% done finished in 2.52s, 1981.37 req/s, 412.14KB/s requests: 5000 total, 5000 started, 5000 done, 5000 succeeded, 0 failed, 0 errored, 0 timeout status codes: 5000 2xx, 0 3xx, 0 4xx, 0 5xx traffic: 1.02MB (1065000) total, 761.72KB (780000) headers (space savings 0.00%), 87.89KB (90000) data min max mean sd +/- sd time for request: 35.61ms 89.74ms 49.25ms 3.17ms 94.78% time for connect: 34.44ms 36.57ms 35.34ms 433us 65.00% time to 1st byte: 70.52ms 125.97ms 97.61ms 15.36ms 59.00% req/s : 19.83 20.20 20.02 0.11 56.00%
スループットは、 1981.37 req/s
で、1st byteの時間、つまりレイテンシやレスポンスタイムと呼ばれる応答があるまでの時間に関しては、こちらは平均 97.61ms
でした。
sanicのページに書かれていたのは、スループットが 2138 req/s
、レイテンシが 46.66ms
なのでスループットはわりと誤差の範囲に収まっている気がしますが、レイテンシは2倍近くの時間差があります。
試しにapache benchでも測ってみました。
apache benchの結果
$ ab -n 5000 -c 100 http://ec2-hoge.ap-northeast-1.compute.amazonaws.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 ec2-52-193-139-58.ap-northeast-1.compute.amazonaws.com (be patient) Completed 500 requests Completed 1000 requests Completed 1500 requests Completed 2000 requests Completed 2500 requests Completed 3000 requests Completed 3500 requests Completed 4000 requests Completed 4500 requests Completed 5000 requests Finished 5000 requests Server Software: TornadoServer/4.4.2 Server Hostname: ec2-52-193-139-58.ap-northeast-1.compute.amazonaws.com Server Port: 80 Document Path: / Document Length: 18 bytes Concurrency Level: 100 Time taken for tests: 3.788 seconds Complete requests: 5000 Failed requests: 0 Write errors: 0 Total transferred: 1065000 bytes HTML transferred: 90000 bytes Requests per second: 1320.01 [#/sec] (mean) Time per request: 75.757 [ms] (mean) Time per request: 0.758 [ms] (mean, across all concurrent requests) Transfer rate: 274.57 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 34 35 0.5 35 41 Processing: 35 38 4.6 38 93 Waiting: 35 38 4.6 38 93 Total: 69 74 4.7 73 129 Percentage of the requests served within a certain time (ms) 50% 73 66% 73 75% 74 80% 74 90% 75 95% 77 98% 80 99% 100 100% 129 (longest request)
スループットが、 1320.01 req/s
と少し小さいようです。
レイテンシの方(Time per request)は平均 75.757ms
とh2loadの結果と近い値がでました。
sanicのREADMEに書いてあるbench scoreと比べると、どちらもレイテンシの差が特に気になります。 よくよく考えると負荷をGCEのインスタンスからかけていたのですが、ネットワークの影響が大きいのかもしれません。 並列100個のリクエストをTornadoに送ったときのhtopを見る限り、MediumインスタンスのCPU・メモリリソースではまだまだ余裕があるので、 Mediumインスタンスの中から負荷をかけて、ネットワークの影響を減らしてみます。
Localhostで試してみる
$ h2load -n 5000 -c 100 localhost:8080 invalid URI: localhost:8080 ubuntu@ip-172-31-22-107:~$ h2load -n 5000 -c 100 --h1 http://localhost:8080 starting benchmark... spawning thread #0: 100 total client(s). 5000 total requests Application protocol: http/1.1 progress: 10% done progress: 20% done progress: 30% done progress: 40% done progress: 50% done progress: 60% done progress: 70% done progress: 80% done progress: 90% done progress: 100% done finished in 2.38s, 2099.97 req/s, 436.81KB/s requests: 5000 total, 5000 started, 5000 done, 5000 succeeded, 0 failed, 0 errored, 0 timeout status codes: 5000 2xx, 0 3xx, 0 4xx, 0 5xx traffic: 1.02MB (1065000) total, 761.72KB (780000) headers (space savings 0.00%), 87.89KB (90000) data min max mean sd +/- sd time for request: 1.27ms 138.37ms 46.64ms 6.02ms 97.68% time for connect: 643us 1.53ms 995us 227us 61.00% time to 1st byte: 2.64ms 139.75ms 35.19ms 33.23ms 92.00% req/s : 21.00 21.66 21.43 0.16 76.00%
スループットが2099.97 req/s、2,138msとくらべてかなり近い値が出ました。 ただ、1st byteまでの時間が2.64msとsanicのREADMEに比べかなり速い結果になってしまいましたね... 一応apache benchも試してみます。
$ ab -n 5000 -c 100 http://localhost:8080/ 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 500 requests Completed 1000 requests Completed 1500 requests Completed 2000 requests Completed 2500 requests Completed 3000 requests Completed 3500 requests Completed 4000 requests Completed 4500 requests Completed 5000 requests Finished 5000 requests Server Software: TornadoServer/4.4.2 Server Hostname: localhost Server Port: 8080 Document Path: / Document Length: 18 bytes Concurrency Level: 100 Time taken for tests: 3.250 seconds Complete requests: 5000 Failed requests: 0 Total transferred: 1065000 bytes HTML transferred: 90000 bytes Requests per second: 1538.36 [#/sec] (mean) Time per request: 65.004 [ms] (mean) Time per request: 0.650 [ms] (mean, across all concurrent requests) Transfer rate: 319.99 [Kbytes/sec] received Connection Times (ms) min mean[+/-sd] median max Connect: 0 0 0.2 0 2 Processing: 1 64 8.6 66 168 Waiting: 1 64 8.6 66 168 Total: 2 64 8.5 66 169 Percentage of the requests served within a certain time (ms) 50% 66 66% 67 75% 67 80% 67 90% 70 95% 73 98% 74 99% 75 100% 169 (longest request)
apache benchの方は、先ほどと同じくh2loadの結果に比べて少しかかった時間が長く、スループットも悪い結果となりました。 リクエストの総数を10倍の50000個にしても、レスポンスタイムやスループットに違いは見られませんでした。 ベンチマーカー側の性能の差でこれぐらいの違いが出てしまうのは仕方ないのかもしれない。
もうちょっとわかったことがあれば追記。 ここがおかしいとかあればコメントもお待ちしてます。
References
今回は試さなかったけど、siegeやvmbench、wrkが使われているのを見かけた。
- 作者: 小出淳子,黒澤剛志,牧大輔,横江亮佑,山口貴也,尾藤正人,佐藤琢哉,中橋研太郎,田中慎司,小西裕介,伊藤直也,稲富駿,前島真一,長野雅広,山際康貴,のざきひろふみ,うらがみ,岡林大,遠藤雅伸,ひげぽん,海野弘成,はまちや2,竹原,大場寧子,大場光一郎,野々下裕子,WEB+DB PRESS編集部
- 出版社/メーカー: 技術評論社
- 発売日: 2016/10/22
- メディア: 大型本
- この商品を含むブログを見る
Apache JMeterメモ
Website: http://jmeter.apache.org/
Apache JMeterを教えてもらったので、後で見返せるようにメモ。
Apache Software Foundationで開発されているオープンソースのJavaアプリケーション Webサーバーに対して複数のHTTPリクエストを送信し負荷をかけたり、JDBCを経由してデータベースサーバーに負荷をかけたりできる
基本的な流れ
起動
最新のzipバイナリをダウンロード・解凍。
$ cd apache-jmeter-3.0/bin $ java -jar ApacheJMeter.jar
スレッドグループ
リクエストを送るためのもの。 よく使うのはHTTP SamplerとJDBC Sampler.
- Host:
192.168.45.10
- Port: 80 (80の場合は省略可)
- Path:
/pukiwiki/
リスナー
負荷はもうかけられるが、結果を見るための設定がない。それがリスナー。
「結果をツリーで表示」と「結果を表で表示」をクリック。
- 結果をツリーで表示からは、リクエストや応答データが見れる
- 結果を表で表示は、ズラッと全部見たい時に便利
- Connect Time: 接続時間
- スレッド数1でループ回数を5とかにすると、keep-aliveが有効なおかげで2回目以降のリクエストのconnect timeが0になるのが確認できる。
- Connect Time: 接続時間
リスナーは何回も実行すると溜まっていくので、「ほうき」のアイコンの「消去」で掃除できる。
実行
「開始」ボタンを押したら開始出来る。
シナリオキャプチャ
ブラウザで操作を記録させて、シナリオを簡単に作ることができる。
HTTPプロキシサーバを追加
- Portは使っていない番号に設定 (ここでは8999)
- 除外するパターンを
.*.css.php.*
と最後にも.*
を付けているのは、クエリパラメータも含めるため
HTTPプロキシの設定
Chromeの「設定」>「詳細設定」>「プロキシ設定の変更」から、上で設定したポート番号を指定。
開始
「HTTPプロキシサーバ」>「開始」を押したら(ここで鍵がどうのこうのってメッセージが出たけどとりあえずOKで進めてみた)、Chromeを開いて検証したいようにブラウザで操作。
終わったら「HTTPプロキシサーバ」>「停止」
これで終わり。緑の「開始」ボタンをクリックすると実行してくれる。
その他
ユーザ定義変数
設定しておくと、次に127.0.0.1とかが出てきた時に、自動で ${PUKIWIKI_HOST}
とかを埋め込んでくれる。
あとでこの変数のvalueを変えるだけで済んで便利。
HTTPリクエストの詳細設定
「Advanced」>「全てのイメージとアプレットを繰り返してダウンロードする」を選択すると、そこのページのCSSや画像も全部ダウンロードしてくれる。
スレッドグループの設定
スレッド数やループ回数以外にもいくつかオプションがある。 例えば、60秒間負荷をかけたい場合は、ループ回数を無限、持続時間を60にすればいい。
MySQL(MariaDB)の計測
Setup
CentOS7にMariaDBを入れる
$ yum update $ yum install mariadb mariadb-server $ systemctl start mariadb $ systemctl enable mariadb
参考: 【jmeter】【MySQL】MySQLからデータを取得し、変数に格納する - たんたんめん日記
MySQL :: Download Connector/J から zipパッケージをダウンロードして展開、 mysql-connector-java-5.1.40-bin.jar
を apache-jmeter-3.0/lib
に入れる。
1つのRDBに負荷をかける
うまくいくとこのようになる。権限周りでちょっとはまりましたが、「結果をツリーで表示」からレスポンスをみて修正。
複数のDBに対してロードバランス
レプリケーションをしていて、マスタや複数のスレーブに対してリクエストを分散させたい場合、
jdbc:mysql:loadbalance://<FQDN or IP address>:<port>,<FQDN or IP address>:<port>/<DB name>
JMeter Server
複数台のPCからリクエストを投げる。 下の記事の通りやったら問題なく動いた。 zipパッケージの中に jmeter-serverとかも最初から入ってて、j
複数台のJMeterサーバで負荷試験を行う方法 | Check!Site
テスト計画の保存
ファイルメニューからテスト計画を保存できる。 XML形式で保存されているので、構造もそれほど複雑ではない。 プログラムとかExcelマクロで生成できそう。
キャプチャ
JMeter Proxy Serverを経由することで、実際のユーザ−の行動からリクエストをキャプチャーしたりできる。
CUI
試してないけど、 *.jmx
で保存して bin/jmeter.bat
から実行出来るらしい。
自動化するならこっちのほうが大事そう。
おわりに
気が向いたら今度、グラフとかレポートがリッチらしいGatlingも使ってみたい。
- 作者: Brendan Gregg,西脇靖紘,長尾高弘
- 出版社/メーカー: オライリージャパン
- 発売日: 2017/02/22
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (1件) を見る
Electronでニコ動のコメントみたいにTweetを表示するアプリつくった
知り合いのエンジニア(rayさん)がGTK3で作っていた nsd というのがあるんですが、結構いい感じなのでMacでも動くものが欲しかった。 Electronで似たようなことが出来ないか調べてみると、GTK3とかに比べて簡単にできそうだったので作ってみた。
ポイントは:
- 常に最前面にtweetが表示される
- マウスのイベントが後ろに透過する
- コーディングだったり他の作業が問題なく出来る
今度、カンファレンスや勉強会で話す時にハッシュタグ表示してみます。
ロゴも描いてみた
マウスのイベントの透過について
rayさんのnsdとかの場合、tweetのテキストを囲うだけのとても小さくて透明なウィンドウを用意していたらしい。こうすることで文字以外のところをクリックすると後ろにマウスのクリックイベントとかが通る仕組み。 透明なウィンドウを作れるGUIツールキットはたくさんあるみたいなのですが、Electronは簡単にマウスのイベントを透過できた。
ハマったところとか参考にした記事
- Electronは半年以上前に、Hello Worldをしただけだったので、今回もQuickStartからやり直した。
- 透明なウィンドウのままで、開発者ツールを使わないとデバッグがかなり難しかった。
- 開発者ツールを開く処理だったりを、もうちょっとカジュアルに環境変数とかで変更できるようにしておくとスムーズだったかも
- Electronでデスクトップいっぱいに雪を降らせるアプリを作る - Qiita
- これを見つけたので今回やってみることにしました。感謝!透過の設定やマウスを通す設定を真似させていただきました。
- tweetのデータをフロントに送る方法で悩んでいたら、 electron/ipc-renderer.md at master · electron/electron · GitHub というのをみつけた。
- とても簡単にIPCができる
- canvasの文字がぼやけて困っていたのですが、canvas自体の解像度(幅と高さ)を調整しないといけなかったみたいです。
- devicePixelRatioというものを教えていただけました。ありがとうございます!
@c_bata_ devicePixelRatio 見てないからじゃないでしょうか? canvas は retina ディスプレイとか考慮してくれないので,自前で倍率調整する必要があると思います.
— ドッグ (@Linda_pp) October 11, 2016
あとやりたいこと
自分が使うには、最低限欲しい機能が全部揃ったのでとりあえず満足。 設定のダイアログとかを追加して、そこから認証してAccess Tokenとったりハッシュタグ指定できるようにしたい。 Issue にあげてるので、おもしろそうと思った方はぜひPRお願いします。
追記
とりあえずMacの右上のバーに常駐させて、色々と設定画面とかも用意中。