Help us understand the problem. What is going on with this article?

Stress Test with Locust written in Python

この記事は Brainpad Advent Calender 2019 2日目の記事になります

こんにちは@nissy0409240です
BrainPadでエンジニアをしています
2019年もあと一ヶ月を切りましたが
皆様いかがお過ごしでしょうか

今年はプライベートで東京ドームへ行くことが出来た
感動の一年でありました
image.png
東京ドームと言えば野球
野球と言えばピッチャーとバッターです
そんな前置きとは無関係に本エントリーでは
Pythonでシナリオを書ける負荷試験ツールLocustの基本的な機能を紹介させて頂きます

Locustとは

LocustとはGUIのインターフェースもついているPython製の負荷試験ツールです
他の負荷試験ツールと比較して一番大きい特徴はPythonでシナリオを書けることです
言葉遊びなようでもありますがPythonでシナリオを書かないといけないとも言えます

公式ドキュメント等の各種リンクはこちらになります

ちなみにLocustはバッタやイナゴという意味の英語です

image.png
イラストはトノサマバッタです

インストール方法

早速インストールしていこうと思います
インストールは下記コマンドを実行するだけです
※Macのローカル(Python3系)で動かすことを前提に進めます

$ brew install libev
$ python3 -m pip install locustio

実行後に$ locust --helpコマンドを実行し、ヘルプが表示されればインストール成功です

image.png
イラストはイナゴです

シナリオを作成

シナリオはPythonスクリプトに記述します。
記述するファイル名自体に制約は有りません。
ですが、起動時にファイル名の指定をしないとlocustfile.pyというファイル名のものが実行されるので
ファイル名の制約が無いのならlocustfile.pyというファイル名にすることをお薦めします。

以下がサンプルです

from locust import HttpLocust, TaskSet, task, between


class WebsiteTasks(TaskSet):
    @task
    def index(self):
        self.client.get('/')


class WebsiteUser(HttpLocust):
    task_set = WebsiteTasks
    wait_time = between(5, 15)

ちなみに受けるAPIサーバーはこんな感じです

from wsgiref.simple_server import make_server

import json


def api(environ, start_response):
    status = '200 OK'
    headers = [
        ('Content-type', 'application/json; charset=utf-8'),
        ('Access-Control-Allow-Origin', '*'),
    ]
    start_response(status, headers)

    return [json.dumps({'message':'hoge'}).encode("utf-8")]

with make_server('', 3000, api) as httpd:
    print("Serving on port 3000...")
    httpd.serve_forever()

image.png
イラストはショウリョウバッタです

起動

下記コマンドにて起動します

$ locust
[2019-12-01 00:56:13,884] locust.main: Starting web monitor at *:8089
[2019-12-01 00:56:13,885] locust.main: Starting Locust 0.9.0

上の例では何もオプションを着けて実行しておりませんが

-fオプションで実行したいシナリオが書かれたファイルを
-Hオプションで叩きたいエンドポイントを指定できます

デフォルトでLocustのプロセスは8089ポートで起動しますが
-Pオプションで起動時のポートを変更することが可能です

ちゃんと指定すると
このように起動します

$ locust -f locustfile.py -H http://localhost:3000 -P 8089
[2019-12-02 03:38:42,717] locust.main: Starting web monitor at *:8089
[2019-12-02 03:38:42,718] locust.main: Starting Locust 0.13.2

image.png
イラストはイナゴの佃煮です

テスト実行

起動後にブラウザからhttp://localhost:8089にアクセスすると
以下のようなGUIにアクセス出来ます

スクリーンショット 2019-12-02 3.39.14.png
先程何気なく指定した叩きたいエンドポイントがデフォルトで設定されています

スクリーンショット 2019-12-02 3.08.26.png
※起動時にHostを指定しない場合、Hostは空欄になります

空欄になっている設定項目があるので、以下の値を入力します
"Number of users to simulate" に100
"Hatch rate" に 1

それぞれの意味は以下の通りです

Number of users to simulate:何クライアント作成するか(最大で秒間何リクエストを送るかと同義)
Hatch rate:クライアントの作成スピード(毎秒ごと)
Host:接続先エンドポイント

今回はhttp://localhost:3000に対して1秒ごとに1クライアントづつ増やしながらリクエストを送信する
この時、最大でもクライアント数は100まで増やすこととする
という条件で実行します

スクリーンショット 2019-12-02 23.36.11.png

入力後「Start Swarming」ボタンを押すとリクエストが実行されます

スクリーンショット 2019-12-02 21.40.38.png

実行を終了させたい場合はブラウザの右上のSTOPボタンを押しましょう
押した後はSTATUSがSTOPPEDになり、終了したことが確認出来ます

スクリーンショット 2019-12-02 21.42.49.png

image.png
イラストはバッタやイナゴの大群です

メトリクス

Chartsタブでメトリクスを見ることも出来ます
スクリーンショット 2019-12-02 22.00.39.png
スクリーンショット 2019-12-02 22.01.34.png
こちらは1秒ごとに1クライアントづつ増やし、最大100クライアントまで増えたらそのまま100クライアントでリクエストし続けた時のメトリクスです

続いて、リクエストに失敗した時はどのようになるか見ていきましょう
今回はAPIサーバーのプロセスを途中で停止してみようと思います

スクリーンショット 2019-12-02 22.44.48.png
スクリーンショット 2019-12-02 22.43.59.png
スクリーンショット 2019-12-02 22.44.18.png
スクリーンショット 2019-12-02 22.44.38.png
各タブにてこのように確認出来ます
失敗したリクエストの増え方やリクエスト全体に対する失敗の割合
Failuresタブではどのような理由で失敗したかも確認出来ます

また、Downloads Dataタブからは結果をダウンロードすることも可能です
スクリーンショット 2019-12-02 23.23.27.png

ダウンロードしたファイルの中身はこのようになっています
スクリーンショット 2019-12-02 23.24.55.png

image.png
イラストはバッタのキャラクターです

結び

以上、基本的な機能のみではございますがLocustの紹介をさせて頂きました
バッターのイラストとともにお別れです
最後までお付き合い頂きありがとうございました

image.png

参考

https://qiita.com/yamionp/items/17ffcc465272ad83c490
https://inside.pixiv.blog/east/5407
https://blog.htmlhifive.com/2015/08/14/web-server-load-testing-tools-2-locust/
https://docs.locust.io/en/stable/installation.html
https://docs.locust.io/en/stable/quickstart.html
https://co3k.org/blog/load-test-by-locust

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away