Locustを触ってみた

# 概要
- これまでJmeterを使っていたが、別の負荷試験ツールにも触れてみたくなったのでLocustにチャレンジ
- とりあえず動かしてみる
- 実務で使いながら随時更新

:::note warn
この記事ではLocust 1系を前提にまとめています。
Locust 2系については以下でまとめています。
:::

https://hirabay.net/?p=228

# 参考

- https://docs.locust.io/
- オプション一覧
  - https://docs.locust.io/en/stable/running-locust-distributed.html#options

# 環境構築

- ここではCentOSベースのサーバーに構築

```bash
# pythonのバージョンを確認
# 2020/01時点のサポートバージョンは「2.7, 3.5, 3.6, 3.7, 3.8」
python --version
> Python 2.7.5

# pipがすでに入っていれば不要
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py
pip --version

# locustインストール
python -m pip install locustio
locust --version
```

- 高負荷なテストを行いたい場合、file open数も気にしておく
- 仮に同時に300リクエストを実効するテストを行いたい場合file openも300以上にしておく必要がある

```bash
# 確認
ulimit -n
> 65535

# 変更したい場合
vi /etc/security/limits.conf
```

# とりあえず動くところまで

## 準備

```locustfile.py
from locust import HttpLocust, TaskSet, task, between, constant

class UserBehavior(TaskSet):
    @task(1)
    def profile(self):
        self.client.get("/sample", verify=False)

class WebsiteUser(HttpLocust):
    task_set = UserBehavior
    wait_time = constant(0)
```

- `verify=False`はhttpsで通信する時にエラーが出たので付与
    - pythonになれてなくてsslのあれこれがよくわかってない...
- pathにはプロトコルや、ホストは記載しない
    - あとでUIで入力する

## 起動

```bash
locust
# これと一緒
# locust -f ./locustfile.py
```

- 8089ポートでUIが起動する

<img width="870" alt="スクリーンショット 2020-01-26 21.12.09.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/19adcf6f-e52c-a995-a873-57b0fd4af763.png">

- Number of total users to simulate
    - 想定ユーザー数
    - アクセス元のスレッド数と考えても良さそう
    - 目標rps = ユーザー数 / (レスポンスタイム + time wait)
- Hatch rate
    - 例えば10と設定すると1秒間に10ずつユーザー数が増えていく
    - maxは「Number of total users to simulate」の設定値
- Host
    - プロトコル＋ホスト＋ポートを指定
    - `http://localhost:8080`とか

Start swarmingで起動！

Chartsタブを見ると試験状況が確認できる！

<img width="1364" alt="スクリーンショット 2020-01-26 21.30.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/3793b2d6-18b6-e2be-9909-ea46f5bedd85.png">

# master/slave構成

- locustはmaster/slaveを使用することでスケーリング可能
- master/slaveの管理のためにこれ以降dockerを使用する

## docker準備

インストール手順は省略
以下のコマンドが叩けることを確認

```
docker-compose --version
docker --version
```

## single構成をdockerで

```dockerfile:Dockerfile
FROM python

RUN pip install locustio

WORKDIR /locust
COPY ./locustfile.py .

CMD ["locust"]
```

起動

```bash
docker run -d \
    -p 8089:8089 \
    --name locust locust

# ストップ&削除
# docker stop locust
# docker rm locust
```

## 次はdocker-composeで

```bash:docker-compose.yml
version: '3'
services:
  locust-single:
    build: .
    ports:
      - "8089:8089"
```

起動

```bash
docker-compose up -d

docker ps
# CONTAINER ID        IMAGE                  COMMAND             CREATED             STATUS              PORTS                    NAMES
# d836d979d4b5        locust_locust-single   "locust"            10 seconds ago      Up 9 seconds        0.0.0.0:8089->8089/tcp   locust_locust-single_1
```

## master/slave

- 起動用シェル作成
    - 環境変数によってモードを切り替え

```bash:run.sh
#!/bin/bash

echo "mode: $MODE"

if [ "$MODE" == 'master' ]; then
  locust --master
elif [ "$MODE" == 'slave' ]; then
  locust --slave --master-host=locust-master
fi
```

- Dockerfileを修正
    - ./run.shを呼び出す

```dockerfile:Dockerfile
FROM python

RUN pip install locustio

WORKDIR /locust
COPY ./locustfile.py .
COPY ./run.sh .

ENTRYPOINT ["./run.sh"]
```

- docker-compose.ymlを修正
    - slaveは一旦３台

```yaml:docker-compose.yml
version: '2'
x-locust-service: &locust-service
  build: .
services:
  locust-master:
    <<: *locust-service
    ports:
      - "8089:8089"
    environment:
      MODE: master
  locust-slave-1:
    <<: *locust-service
    environment:
      MODE: slave
  locust-slave-2:
    <<: *locust-service
    environment:
      MODE: slave
  locust-slave-3:
    <<: *locust-service
    environment:
      MODE: slave
```

起動！

```bash
docker-compose -f docker-compose-master-slave.yml up -d
# 開発時は毎回build
# docker-compose -f docker-compose-master-slave.yml up -d --build
```

<img width="858" alt="スクリーンショット 2020-01-26 23.42.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/361020/9cc531fd-da6a-081c-dd75-21897c2be1ce.png">

slavesが３になってる！！！