Locust を Heroku で動かして大規模負荷テストを実行してみよう

Herokuでのアプリケーション開発のみならず、システムの開発も佳境になり、負荷テストをかけるようなタイミングは通常やってくるでしょう。Heroku では、[loader.io](https://elements.heroku.com/addons/loaderio)を利用できるアドオンを提供していますので、こちらで負荷テストを簡単に仕掛けることができます。しかし、[loader.io](https://elements.heroku.com/addons/loaderio)のPro版でも、次の制約があります。

- 負荷テストは10分まで
- 同時アクセスユーザーは100,000ユーザーまで
- 1テストにおけるURL(URI)は10個まで

これらよりも多く使いたい指定したい場合、長い時間不可を欠け続けたいような場合には、[loader.io](https://elements.heroku.com/addons/loaderio)では実行できない場合があります。また、実行元をTokyo Regionにしたいといったことも指定できません。このとき、Herokuの環境があれば、Heroku上に負荷テストツールを入れて仕掛ければ良いのでは...と考えるのは自然の摂理です。そうです、Heroku でも負荷テストを実施してみましょう。

では、ということで某JMeterで負荷テストをするべく、Heroku Private Space を活用して、なんとか Master/Slave構成で実行できるようにしてみたのですが、どうにもパフォーマンスが出ず。チューニングに心血を注ぐ力も残っていなかったところで、[Locust](https://locust.io/)を教えていただいてめぐりあいました。これがホントに素晴らしい。

- 何が素晴らしいかって、管理画面がWeb ![Locustイメージ](https://locust.io/static/img/screenshot.png)
- Master/Slave構成が簡単に構成できる
- Python のコードちょっと書けば動く

／(^o^)＼ﾅﾝﾃｺｯﾀｲ Heroku で簡単に動かせるじゃん!!! ということで、Herokuに実装して、コードも何もかも公開しました。

https://github.com/sho7650/heroku-locust

こちらでは、実装方法について紹介しておきます。なお、JMeter on Herokuの苦戦した様子は、今後どっかで公開していきます。

# Heroku で Locust を動かす。

Github上の[ソースコード](https://github.com/sho7650/heroku-locust)をDeployしてもらえれば、すぐに動かせる状態になりますが、[Locust](https://locust.io)を一から動かしてみたい人用にいくつかTipsを載せておきます。

## 1台構成、及び Master/Slave構成共通の留意事項

1. 24時間以上の負荷テストは実施できません
2. `web` dynoの起動ポートは `$PORT` を指定すること
3. CUIで実行するのは一旦忘れましょう

Heroku の dynoは、24時間+αでリスタートする仕様がありますので、どうあがいてもそれ以上の時間、負荷をかけ続けることはできません。ご了承ください。そんなにかけることはイヤガラセ以外にはないと思うので、問題ないと思いますが。

LocustはCLIでバッチ的に処理することも可能です。ですが、結果を外部へ送る仕組みなどを考慮するとそれだけで連載一回分になりますので、今は忘れましょう。今度うまい方法を見つけたら、また書き記します。

## Master/Slave構成にしたい場合

1. Private Space が必須
2. Master は `web` Dyno を1台、Slave は `worker` Dyno として動かす
3. Slaveが Masterのアドレスを指定する際に `HEROKU_DNS_APP_NAME` 環境変数をうまく使う

3の点について補足します。実際に見てもらったほうが早いので、Master/Slave時の`Procfile`を確認ください。

```:Procfile
web: locust -P $PORT --master
worker: locust --slave --master-host=1.web.${HEROKU_DNS_APP_NAME}
```

[Private Spaces DNS Service Discovery](https://devcenter.heroku.com/articles/dyno-dns-service-discovery)機能を利用して、Slaveたる`worker` Dynoたちから、Masterのホスト名を指定します。このとき、自分自身の Herokuアプリ名が必要になります。その内容を確認できる環境変数が`HEROKU_DNS_APP_NAME` になるので、これを指定して`web` Dynoのアドレスを指定しています。

Masterは1台固定となりますので、`web` Dynoの 1番目を Masterのアドレスとして指定しています。

なお、`worker`として動かす dynoを増やせば増やしただけ、Slaveを増やして実行させることができます。ここが Locustの素晴らしく良いところです。大変便利、めっちゃ楽、ほんとにありがとう!!

# Github の heroku-locust を使いたい

先ほど紹介した[heroku-locust](https://github.com/sho7650/heroku-locust)を開いて、「Heroku Button」を押せばdeployできます。こちらのソースコードでは、Master/Slave構成になっているので、Private Spaceでなければ、動きません(deployもできません)。

次のような画面が出てきますので、お持ちの Private Spaceを選択していただいて、画面上の次の4つの環境変数を適宜設定していただければ、それだけでdeployできます。

![Screen Shot 2019-04-18 at 12.55.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/37263/6d2af172-de99-41b1-0370-4a2fcc2bd416.png)

## 環境変数

設定できる環境変数は次の4つです。

1. HOSTNAME
2. URI1
3. MIN_WAIT
4. MAX_WAIT

### HOSTNAME

負荷テストを仕掛ける相手先のホスト名を指定します。HTTPのスキーム名も必要なので、`https://www.example.com` のように指定します。

この項目の設定は必須です。

### URI1

負荷テスト先の`URI`を指定します。ホスト名以降の '/' で始まる URIパスを入れます。Heroku Button では `URI1` しか指定できないようにしていますが、複数のテスト先を指定したい場合は URI2, URI3,... と数字を増やしていって登録すれば、複数のURIをテスト実施できます。

### MIN_WAIT

`Locust`で指定される`min_wait`を定義します。

### MAX_WAIT

`Locust`で指定される`max_wait`を定義します。

---

non Private Space 版もできたら公開します。