ruby

2011年03月18日

負荷試験ツール「インターネット破壊」を公開しました

はてなブックマークに登録

負荷試験ツール インターネット破壊を公開しました。

こちらはずっと社内で負荷試験に使用していたツールです。社内で使用していたものなので、ソーシャルアプリ向けの機能などが多少追加されていますが、もちろんんそれ以外のWebアプリケーションでも使用できます。

基本的にはApache JMeterのようなWebアプリケーションむけのシナリオ負荷試験ツールです。コマンドラインオペレーションだけで実行でき、サーバー上で簡単に負荷試験を実施できるのが特徴です。POSTリクエストなどはもちろん、レスポンスのチェックやUserAgentの偽装、ランダムな値をパラメーターにセットする機能も実装しています。

注意: 当然ながら自分の管理下にないサイトに向けて負荷試験ツールを実行するのは絶対にやめてください。非常に危険です。

物騒な名前がついていますが、これは完全にわたしの小児的感性の趣味によるところです。地震で人々が苦しんでいるところに「破壊」という名前もどうなのかと思っていたのですが、名前はあくまでも名前にすぎず、実態は負荷試験ツールですので、変に遠慮するのはやめて公開することにしました。

地震の際、電話などが機能しなくなるなか、Twitterや GoogleのPerson FinderなどのWebアプリケーションが災害時の情報交換に役立ったのは周知の事実です。そして災害時などにアクセスが殺到してもサービスを平常に行なうためには、負荷試験が必要です。頑強なWebアプリケーションを開発するために、このツールが役立てば個人的には非常にうれしいです。

インストール方法

rubygemsに登録されているため、以下のコマンドライン操作でインストールできます。RubyRevというイベント駆動のフレームワークを使用しているので、そちらも同時にインストールされます。

$ gem install internethakai

ソースコードや詳細なドキュメントは以下のサイトにまとめています。

http://internethakai.rubyforge.org/

チュートリアル

簡単な試験を実行してみましょう。

まずシナリオのテンプレートを生成します。

$ hakaigen
your site
    ex. http://example.com
> example.com
save to scenario-0.yml

scenario-0.ymlというファイルにベースとなる設定ファイルが保存されました。actionsという項目をいじります。シナリオはyml形式です。

actions:
  -
    path: /top/index
  -
    path: /item/confirm
  -
    path: /item/doBuy
    method: POST
    post_params:
      id: 12
      category: 2

以上のようにpathをならべて書いていけば大丈夫です。POSTの箇所はmethodをPOSTと指定し、パラメーターをつけます。

以下のコマンドで実行します。--testオプションをつけると、ログレベル3、同時リクエスト数1で実行します。

$ internethakai scenario-0.yml --test

ログレベルを4にすると、レスポンスの中身まで確認できます。

$ internethakai scenario-0.yml --log=4

同時リクエスト数を50まで増やします。

$ internethakai scenario-0.yml -r 50

100回ループさせます。

$ internethakai scenario-0.yml -r 50 -l 100

5分間(300秒)試験を継続させます。

$ internethakai scenario-0.yml -r 50 -d 300

破壊力をあげるため、4プロセスで実行してみます。

$ internethakai scenario-0.yml -r300 -p4 -d300

これと同時に、負荷試験を実行しながら、cactiやgangliaなどのレポートツールでサーバーの状態を確認します。

また実行が終了すると、インターネット破壊の側にもデータが表示されるので、レスポンスに時間のかかるパスなどを確認できます。

Target domain = http://example.com
Loop: 1
Request Concurrency: 10
Scenario Concurrency: 10
ooooooO
result: failure

TimePerRequest: 466.763428571429
RequestPerSec: 21.4241292009657


MinResponse Worst:
        1: /top/index 66.806 20
        2: /shop/confirm 26.582 10
        3: /shop/doBuy 26.072 10
AvgResponse Worst:
        1: /shop/doBuy 252.2343 20
        2: /top/index 39.0615 10
...

上では、POSTリクエストにつけるアイテムのIDなどを固定にしましたが、実際の試験ではランダムなIDを指定したい場合もあります。

actions:
  ...
  -
    path: /item/doBuy
    method: POST
    post_params:
      id: 12 # ←ここをランダムに変更したい!
      category: 2

まず1から100までの値を書いたファイル(改行区切り)を用意します。

$ ruby -e "1.upto(100){|i| puts i.to_s}" > ids

こちらを変数として利用するように設定ファイルを書き換えます。

vars:
  -
    var_file: ./ids
    var_name: item_id

actions:
...
  -
    path: /item/doBuy
    method: POST
    post_params:
      id: %(item_id)% # ←ここをランダムに変更したい!
      category: 2

この状態で実行すれば、1回のシナリオごとに異なる値が使用されます。

$ internethakai scenario-0.yml -r50 -d300

(takada-at)

klab_gijutsu2 at 16:50|この記事のURLComments(4)TrackBack(0)
2010年06月17日

並列1000コネクションに耐える! Ruby のイベント駆動ライブラリ Rev と EventMachine の HTTPクライアント

はてなブックマークに登録

こんにちは、takada-at です。
Rubyのイベント駆動型ネットワークプログラミングフレームワーク Rev と EventMachine で HTTPクライアントを動かしてみました。
イベント駆動型ネットワークプログラミングフレームワークとは何か説明しだすと難しいですが、一言で言うと、以下のようになります。
# ふつうのフロー駆動型プログラム
Net::HTTP.start(host, port){|http|
    res = http.get(path) #この処理が終わってから
}
puts "done" #この次の処理が実行される
# イベント駆動型プログラム
client = Rev::HttpClient::connect(host, port)
client.get(path) #この処理が終わってないのに
puts "not done" #すぐこの行が実行されてしまう
一見するとプログラムの複雑さが増えるだけのように思えますが、処理をブロックしないということは無駄がないということでもあります。これによって、
  • 複数のファイルディスクリプタを同時に開き
  • 読み込み可能なものから処理していく
なんてこともできるようになります。I/O多重化、ノンブロッキングI/O と呼ばれる方法です。


イベント駆動ライブラリのサンプルでは、サーバーを書くことが多いですが、クライアントの同時接続数の限界に挑戦したかったので、今回は HTTPクライアントを書いてみます。


Ruby のイベント駆動ライブラリとして Ruby Revと EventMachine の2つを使ってレスポンスタイムを計測しました。どちらも独自の HTTPクライアントをライブラリに組み込んでいます。

EventMachine
http://rubyeventmachine.com/

Rev
http://rubyforge.org/projects/rev/


RevEventMachine も Python の TwistedTornado、Perl の AnyEvent のように、ノンブロッキング I/O を利用することで並行性が高く高速なネットワークプログラムを組むためのフレームワークです。


どちらのライブラリもまだあまり資料がありませんが、内部の実装を見つつサンプルコードを作成してみました。
結論から言うと、Revはとても高速です。


サーバー側では単純に100ms待ってからレスポンスを返すだけのページを用意しておき、クライアントは並列に接続してレスポンスタイムの平均を取りました。要するに、並列数を増やしてもレスポンスタイムが100ms に近ければ近いほど、高速なクライアントということになります。
以下
  • Rubyのスレッド + net/http ライブラリ
  • Rev/HttpClient
  • EventMachine/HttpClient2
の3パターンで試しました。Ruby の バージョン は 1.8.7 です。
なお、試験に利用したサーバーは、Python の Tornado で書かれており、十分に高速です。
(EventMachine にはなぜか HTTPクライアントが2つありますが、HttpClient という名前の方はまともに動作しなかったので試験対象から外しました)。


10コネクション
target: http://hornet.klab.org:8000/
concurrency: 10
net/http + thread
        avg: 140.5132
EventMachine/HttpClient2
        avg: 101.3227
Rev/HttpClient
        avg: 101.4915

スレッドの方はすでに多少の遅延が派生してます。


100コネクション
target: http://hornet.klab.org:8000/
concurrency: 100
net/http + thread
        avg: 166.59175
EventMachine/HttpClient2
        avg: 110.23086
Rev/HttpClient
        avg: 103.69137

EventMachine, Rev はほぼ問題の無い処理時間です。


500コネクション
target: http://hornet.klab.org:8000/
concurrency: 500
net/http + thread
        avg: 2720.349032
EventMachine/HttpClient2
        avg: 132.847788
Rev/HttpClient
        avg: 113.132662

EventMachine に多少の遅延が発生するようになりました。スレッドはほとんど使いものにならない遅さです。


1000コネクション
target: http://hornet.klab.org:8000/
concurrency: 1000
net/http + thread
        avg: 10968.612545
EventMachine/HttpClient2
        avg: 136.243228
Rev/HttpClient
        avg: 122.174841


EventMachine もかなり高速ですが、1000を少し越えたあたりからまともに動作しなくなります。
一方 Rev は1000コネクション程度でも問題なく動作するようです。



なお注意事項として、この試験をする前に、ファイルディスクリプタの制限を増やしておく必要があります。
デフォルトでは1024以上のファイルディスクリプタを扱うことができず、ソケットの数にも制限がくわえられてしまいます。
Linux では、/etc/security/limits.conf を編集することでユーザーのファイルディスクリプタの上限を増やすことができます。



さらに、TIME_WAIT 状態のコネクションを使い回せるようにtcp_tw_reuse=1 を設定しておくとよいでしょう。
/etc/sysctl.conf に net.ipv4.tcp_tw_reuse = 1 を設定することで、TIME_OUT 状態のコネクションを再利用し、TCPコネクションの上限を引き上げることができます。



以下に今回使用したテストコードを掲載します。
イベント駆動を駆使してるため多少読みにくいですが、どのパターンも 1秒待ってからHTTPリクエストを並列に送信し、レスポンスの時間を計測しています。

(takada-at) 続きを読む
klab_gijutsu2 at 21:53|この記事のURLComments(2)TrackBack(0)
Blog内検索
Archives
このブログについて
DSASとは、KLab が構築し運用しているコンテンツサービス用のLinuxベースのインフラです。現在5ヶ所のデータセンタにて構築し、運用していますが、我々はDSASをより使いやすく、より安全に、そしてより省力で運用できることを目指して、日々改良に勤しんでいます。
このブログでは、そんな DSAS で使っている技術の紹介や、実験してみた結果の報告、トラブルに巻き込まれた時の経験談など、広く深く、色々な話題を織りまぜて紹介していきたいと思います。
最新コメント