Go言語のhttp負荷テストツールVegetaを使ってBlueMixを試す

# Go言語のhttp負荷テストツールVegetaを使ってBlueMixを試す

## Vegetaとは

Go言語で書かれているhttpの負荷テストツールです。
github上で公開されており、[README.md](https://github.com/tsenart/vegeta/blob/master/README.md)にこのツールの名称が何を指しているのかが分かりやすく描かれています。
個人的には負荷のかけ方が『vegeta attack』というコマンドを使う所に惹かれました

https://github.com/tsenart/vegeta

### Vegetaの入手の仕方

gitがclone出来る状態で[GVM](https://github.com/moovweb/gvm)等を使ってGoをインストールしていれば
以下のコマンドで利用可能になります。

```
$ go get github.com/tsenart/vegeta
$ go install github.com/tsenart/vegeta
```

今回はローカルの場所にユーザの領域部分（sudoが不要な場所）にセットアップしていきます。

#### GOPATHの設定

```
$ mkdir http-load-test
$ cd http-load-test
$ export GOPATH=$PWD
```

#### vegetaをhttp-load-testのは以下に落とす

以下のコマンドを実行するとbinの下にvegetaというファイルが出来ます

```
$ go get github.com/tsenart/vegeta
$ ls bin/
vegeta
$ cd bin/
```

### Vegetaの基本的な使い方

以下のように記述すると動作します

```
$ echo "GET http://localhost/" | ./vegeta attack -rate=100 -duration=5s | ./vegeta report
```
『echo』部分でリクエストのURL
『vegeta attack』部分で『-rate=100』で秒間100リクエストを『-duration=5s』で5秒間行います。
『vegeta report』で実行した結果を画面に出力します

## BlueMix(Cloud Foundry v2環境）へアプリをpush


今回はCFの上で動く簡単なアプリが入っている[cf-acceptance-tests](https://github.com/pivotal-cf-experimental/cf-acceptance-tests.git)のasstesの中にある[dora](https://github.com/pivotal-cf-experimental/cf-acceptance-tests/tree/master/assets/dora)というアプリを使ってみます 

cf-acceptance-testsのcloneしdoraをBlueMixへpush

```
$ git clone https://github.com/pivotal-cf-experimental/cf-acceptance-tests.git
$ cd cf-acceptance-tests/assets/dora/
$ cf push cf-dora -i 1 -m 128m

途中のログは省略..

requested state: started
instances: 1/1
usage: 128M x 1 instances
urls: cf-dora.ng.bluemix.net

     state     since                    cpu    memory          disk
#0   running   2014-03-01 05:00:05 PM   0.0%   17.7M of 128M   60.6M of 1G
```

『-i 1』でインスタンス1を指定し
『-m 1』で1インスタンスアプリあたりに128mメモリを割り当てています

curlコマンドで確認してみます

```
$ curl http://cf-dora.ng.bluemix.net/
Hi, I'm Dora!
```

## vegetaを使ってアクセス(doraのインスタンスは1）

### 秒間100リクエストを5秒間

```
$ echo "GET http://cf-dora.ng.bluemix.net/" | ./vegeta attack -rate=100 -duration=5s | ./vegeta report
2014/03/01 17:09:18 Vegeta is attacking 1 targets in random order for 5s...
2014/03/01 17:09:25 Done!
2014/03/01 17:09:25 Writing results to 'stdout'...
Requests        [total]                         500
Duration        [total]                         4.990176005s
Latencies       [mean, 50, 95, 99, max]         437.373852ms, 403.273227ms, 896.467786ms, 1.717192664s, 1.717192664s
Bytes In        [total, mean]                   6500, 13.00
Bytes Out       [total, mean]                   0, 0.00
Success         [ratio]                         100.00%
Status Codes    [code:count]                    200:500
Error Set:
```

### 秒間200リクエストを5秒間

```
$ echo "GET http://cf-dora.ng.bluemix.net/" | ./vegeta attack -rate=200 -duration=5s | ./vegeta report
2014/03/01 17:10:33 Vegeta is attacking 1 targets in random order for 5s...
2014/03/01 17:10:39 Done!
2014/03/01 17:10:39 Writing results to 'stdout'...
Requests        [total]                         1000
Duration        [total]                         4.994420753s
Latencies       [mean, 50, 95, 99, max]         351.303528ms, 318.704129ms, 530.301522ms, 903.208726ms, 903.208726ms
Bytes In        [total, mean]                   13000, 13.00
Bytes Out       [total, mean]                   0, 0.00
Success         [ratio]                         100.00%
Status Codes    [code:count]                    200:1000
Error Set:
```

### 秒間250リクエストを5秒間

```
$ echo "GET http://cf-dora.ng.bluemix.net/" | ./vegeta attack -rate=250 -duration=5s | ./vegeta report
2014/03/01 17:14:52 Vegeta is attacking 1 targets in random order for 5s...
2014/03/01 17:15:05 Done!
2014/03/01 17:15:05 Writing results to 'stdout'...
Requests        [total]                         1250
Duration        [total]                         4.99517956s
Latencies       [mean, 50, 95, 99, max]         3.614812498s, 3.673411212s, 6.336981528s, 6.496029661s, 6.826508395s
Bytes In        [total, mean]                   13559, 10.85
Bytes Out       [total, mean]                   0, 0.00
Success         [ratio]                         83.44%
Status Codes    [code:count]                    200:1043  0:207
Error Set:
Get http://cf-dora.ng.bluemix.net/: dial tcp 75.126.70.44:80: too many open files
```

200以外がちらほら出てくる

## vegetaを使ってアクセス(doraのインスタンスは2）

### まずはじめにcfコマンドを使って『dora』のインスタンス数を2にします

```
$ cf scale cf-dora -i 2
Scaling app cf-dora in org hogehoge@hogehoge.com/ space dev as hogehoge@hogehoge.com...
OK
```


### 再度秒間250リクエストを5秒間

```
$ echo "GET http://cf-dora.ng.bluemix.net/" | ./vegeta attack -rate=250 -duration=5s | ./vegeta report
2014/03/01 17:21:42 Vegeta is attacking 1 targets in random order for 5s...
2014/03/01 17:21:49 Done!
2014/03/01 17:21:49 Writing results to 'stdout'...
Requests        [total]                         1250
Duration        [total]                         4.99567373s
Latencies       [mean, 50, 95, 99, max]         1.129867175s, 1.202581072s, 1.893686575s, 3.58801983s, 3.58801983s
Bytes In        [total, mean]                   13858, 11.09
Bytes Out       [total, mean]                   0, 0.00
Success         [ratio]                         85.28%
Status Codes    [code:count]                    200:1066  0:184
Error Set:
Get http://cf-dora.ng.bluemix.net/: dial tcp 75.126.70.44:80: too many open files
```

## 今度は1インスタンスに戻し秒間250リクエストを1秒間にして確認

### cfコマンドを使って『dora』のインスタンス数を1にします

```
$ cf scale cf-dora -i 1
Scaling app cf-dora in org hogehoge@hogehoge.com/ space dev as hogehoge@hogehoge.com...
OK
```

### 秒間1000リクエストを1秒間

```
$ echo "GET http://cf-dora.ng.bluemix.net/" | ./vegeta attack -rate=1000 -duration=1s | ./vegeta report
2014/03/01 17:34:20 Vegeta is attacking 1 targets in random order for 1s...
2014/03/01 17:34:25 Done!
2014/03/01 17:34:25 Writing results to 'stdout'...
Requests        [total]                         1000
Duration        [total]                         1.045985158s
Latencies       [mean, 50, 95, 99, max]         1.988395448s, 1.97215095s, 3.519185002s, 4.821988844s, 4.821988844s
Bytes In        [total, mean]                   13000, 13.00
Bytes Out       [total, mean]                   0, 0.00
Success         [ratio]                         100.00%
Status Codes    [code:count]                    200:1000
Error Set:

```

### 秒間1250リクエストを1秒間

```
$ echo "GET http://cf-dora.ng.bluemix.net/" | ./vegeta attack -rate=1250 -duration=1s | ./vegeta report
2014/03/01 17:35:26 Vegeta is attacking 1 targets in random order for 1s...
2014/03/01 17:35:43 Done!
2014/03/01 17:35:43 Writing results to 'stdout'...
Requests        [total]                         1250
Duration        [total]                         1.243986787s
Latencies       [mean, 50, 95, 99, max]         7.664525424s, 6.135629385s, 14.681166477s, 14.772027172s, 15.35050538s
Bytes In        [total, mean]                   13260, 10.61
Bytes Out       [total, mean]                   0, 0.00
Success         [ratio]                         81.60%
Status Codes    [code:count]                    200:1020  0:230
Error Set:
Get http://cf-dora.ng.bluemix.net/: dial tcp 75.126.70.44:80: too many open files
```

### 再度秒間1250リクエストを1秒間

```
$ echo "GET http://cf-dora.ng.bluemix.net/" | ./vegeta attack -rate=1250 -duration=1s | ./vegeta report
2014/03/01 17:41:29 Vegeta is attacking 1 targets in random order for 1s...
2014/03/01 17:41:40 Done!
2014/03/01 17:41:40 Writing results to 'stdout'...
Requests        [total]                         1250
Duration        [total]                         1.195024125s
Latencies       [mean, 50, 95, 99, max]         2.980611716s, 1.86887065s, 9.705554255s, 10.104980107s, 10.104980107s
Bytes In        [total, mean]                   16250, 13.00
Bytes Out       [total, mean]                   0, 0.00
Success         [ratio]                         100.00%
Status Codes    [code:count]                    200:1250
Error Set:
```

今度は通りました

## まとめ

* 1インスタンスから2インスタンスにしても変わらず
* 5秒間で1250リクエストでも、1秒間に1250リクエストでも概ね変わらず

この辺りの原因は以下が考えられると思います。

* vegetaを使う側のマシンが原因 or Vegetaの限界？
* あるいはdoraのフロント側にいる『ロードバランサ』 or 『Gorouter』と呼ばれるアプリのルーティングを司る部分
* doraに起因

1000リクエストを超えると揺らぐ部分について、細かい所の原因は深く追えていませんが
とはいえgo getコマンドでサクッとこのようなツールが入って簡単に試せるので
[vegeta](https://github.com/tsenart/vegeta.git)は便利なツールだと思います


vegetaその他の細かい使い方等の説明は[README.md](https://github.com/tsenart/vegeta/blob/master/README.md)を参照してください