locustを用いた負荷テスト

## 今回やること
最近仕事でとあるWEBアプリケーションを作成しました。
このアプリにlocustというツールで負荷をかけることで、CPU使用率やメモリ使用率がどの程度上がるのかを検証してみようと思います。

## テスト概要
今回作成したアプリはユーザーがログインした後にデータを閲覧、検索できる機能を実装しています。
以下の順番でリクエストを送りまくり、サーバーがどの程度の負荷に耐えられるか検証していきます。
1.ログイン
2.閲覧
3.検索

ちなみに本番環境に負荷を掛けまくるわけにはいかないため、自宅内に構築したサーバーでテストを行なっています。

## locustとは
httpリクエストを一度に大量に送れるツールです。pythonでテストシナリオを書くことができます。
locustで辞書を引くとイナゴと出てくるので、蝗害から名前をとっていると思います。


## テスト内容
以下のようにpythonで書きました。

```python
from locust import HttpUser, TaskSet, task
from lxml import html
import re

class UserBehavior(TaskSet):
    # ログイン
    def on_start(self):
        response = self.client.get("/login")
        tree = html.fromstring(response.text)
        authenticity_token = tree.xpath('//form/input[@name="authenticity_token"]/@value')[0]
        self.client.post("/login", {"username": "test", "password": "123456", 'authenticity_token': authenticity_token})

    # ログアウト
    def on_stop(self):
        self.client.delete("/logout")

    # 閲覧
    # @taskは処理の頻度を表す。@task(2)は@task(1)より2倍の頻度で実行される。
    @task(1)
    def top(self):
        self.client.get("/hoge")

    # 検索
    @task(2)
    def search(self):
        self.client.get("/hoge/search?utf8=✓&id=128&OCR=検索文字列", catch_response = True)

class WebUser(HttpUser):
    tasks = [UserBehavior]
```

## テスト実施
locustをインストールして、ターミナルからlocustを起動させます。

```
locust -f テストファイルのパス --host=負荷をかけるサーバーのURL
```

locustを起動してhttp://0.0.0.0:8089/ にアクセスするとブラウザからlocustを操作できるようになります。
こんな感じの画面になるので、各項目に入力しましょう。

・Number of total users to simulate
テストを行うユーザー数を指定します。10を指定したら10ユーザーという感じです。

・Spawn rate
ユーザーを1秒ごとにいくつ増やすかを指定します。
「Number of total users to simulate」で100を指定し、「Spawn rate」で10を設定した場合、1秒に10ユーザーずつ増えていき10秒後に100ユーザとなります。それ以上ユーザーは増加しません。
![スクリーンショット 2021-01-21 23.40.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/ebc82683-ae01-48f0-e2ae-363611f10dae.png)

##　テスト実施
テストを実施すると、chartsタブでリクエスト数、レスポンスタイム、ユーザー数を確認できます。
![スクリーンショット 2021-01-21 23.44.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/355a9e1f-a68a-535d-d38c-a1f230c7be1e.png)
![スクリーンショット 2021-01-21 23.44.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/429077/bad8ded1-cadb-8f91-5631-85892573cce2.png)

## どのぐらい負荷がかかったか？
実際にtopコマンドで確認してみました。
私が建てたサーバーはcpuが６コアなので、load averageをみる限り100ユーザーぐらいなら捌けそうです。

```
top - 23:48:04 up 6 days,  3:34,  1 user,  load average: 2.48, 1.40, 0.60
Tasks: 208 total,  12 running, 196 sleeping,   0 stopped,   0 zombie
%Cpu(s): 22.5 us,  2.5 sy,  0.0 ni, 74.6 id,  0.0 wa,  0.0 hi,  0.4 si,  0.0 st
KiB Mem :  3861360 total,  1197528 free,  1263504 used,  1400328 buff/cache
KiB Swap:  1679356 total,  1679356 free,        0 used.  2343264 avail Mem 

   PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND                                                                                                                                                                              
  4251 hoge      20   0  507372 106764   4284 R  24.9  2.8   2:06.21 ruby                                                                                                                                                                                 
  4239 hoge      20   0  507372 106744   4264 R  24.6  2.8   2:06.20 ruby                                                                                                                                                                                 
  4231 hoge      20   0  507372 106744   4256 R  23.6  2.8   2:06.93 ruby                                                                                                                                                                                 
  4235 hoge      20   0  507372 106740   4256 R  23.6  2.8   2:06.51 ruby                                                                                                                                                                                 
  4243 hoge      20   0  507372 106768   4288 R  22.9  2.8   2:06.60 ruby                                                                                                                                                                                 
  4247 hoge      20   0  509532 107104   4596 R  22.9  2.8   2:06.64 ruby                                                                                                                                                                                 
  2372 nginx     20   0   47268   2392    876 R   2.3  0.1   0:07.12 nginx                                                                                                                                                                                
  2373 nginx     20   0   47268   2392    876 R   2.3  0.1   0:08.04 nginx                                                                                                                                                                                
  2374 nginx     20   0   47268   2392    876 R   2.0  0.1   0:10.92 nginx                                                                                                                                                                                
  2371 nginx     20   0   47268   2388    876 R   1.3  0.1   0:06.00 nginx                                                                                                                                                                                
  2375 nginx     20   0   47268   2392    888 S   1.3  0.1   0:07.29 nginx                                                                                                                                                                                
  2370 nginx     20   0   47268   2392    876 R   1.0  0.1   0:05.49 nginx
```

## まとめ
以上のようにテストを行うことで、サーバーがどの程度の負荷に耐えられるかテストしました。
インフラ側のお勉強にもなったので、ちょっとレベルアップしたと思います。