メモ_Pythonでの良さげな負荷テストツール「Locust」

Python環境で使える良さげなWeb負荷テストツール「Locust」を試してみました。

 

テスト実行側(Locustを実行する方)環境:

Ubuntu 22.04 LTS

Python 3.12.0

vCPUS : 3

Mem : 4GB

 

テスト対象側環境:

Ubuntu 22.04 LTS

Python 3.10.12

Webアプリ : Flask 3.0.0、Waitress 2.1.2、Nginx 1.18.0、MySQL 8.0.35

vCPUS : 3

Mem : 2GB

 

 

準備:

適当な環境を用意して、いつものpipでinstallします。


    pip install locust
    

LocustはGUIの画面があるので、そこへのアクセスとして8089ポートも空けておきます。

負荷テストの内容を記述して、Locustを起動:

以下のような負荷テストのコードを記載して、locustfile.pyというファイル名で保存します。


from locust import HttpUser, TaskSet, task, between

class UserBehavior(TaskSet):
    @task(1)
    def index(self):
        self.client.get("/index")

    @task(2)
    def about(self):
        self.client.get("/about")

class WebsiteUser(HttpUser):
    tasks = [UserBehavior]
    wait_time = between(0.1, 2.0)  # 0.1〜2秒でランダムな待機時間
        
    

上記のコードは基本的なものですが、UserBehaviorクラスは負荷テストの定義です。
@taskデコレータの引数はタスクの重みで、この場合、aboutタスクはindexタスクの2倍の頻度で実行されます。

準備ができたら、以下のコマンドを実行します。-host 引数 の http://target.com が実際に負荷テストをかけるWebサイトになります

locust -f locustfile.py --host=http://target.com
負荷テストの実行:

上記を実行すると、Starting web interface at http://0.0.0.0:8089 というようなメッセージがターミナルに表示されますので、http://localhost:8089 にアクセスします。8089ポートが閉じている場合は当然アクセスできないのでご注意。

無事にアクセスできると以下のような奇麗なGUI画面が表示されます。

Number of total usersは、同時にテストを行う仮想ユーザーの数を指定します。

Ramp up は一秒間で生成させるユーザー数を指定します。

上記の画像の場合、最大100ユーザーを秒間10ユーザーづつ生成していきます。

「Start」ボタンをクリックすると負荷テストが開始されます。

 

実行画面:

以下のように負荷テストの進捗がGUIで見ることができます。

 

停止したい場合は、画面内のSTOPボタンをクリックします。

手動ではなく、指定した時間で自動停止させたい場合は、スタート画面/NEW画面のAdvanced optionsで指定するか、起動時のコマンドで以下のようにします。下記の例では600秒で自動停止します。


timeout 600 locust -f locustfile.py --host=http://example.com
        

連番になっているURLにランダムにアクセスさせたい場合は、以下のように書きます。


class UserBehavior(TaskSet):
    def on_start(self):
        # 連番のURLリストを生成
        self.urls = [f"/{i}" for i in range(1, 101)]

    @task
    def random_url(self):
        # ランダムにURLを選択してアクセス
        url = random.choice(self.urls)
        self.client.get(url)    
負荷のコントロール:

同時ユーザー数、秒間生成ユーザー数、wait_timeの設定値などで細かく制御できそうですが、同時ユーザー数と秒間生成ユーザーを10、wait_timeを0.1秒にして1分間で実行したところ、トータルのリクエスト数が3500程度、RPS(1 秒あたりのリクエスト数)が63程度になりました。ユーザー数を5にしたところRPSが36、ユーザー数を20にしたところRPSが139になったので、負荷対象のWebアプリが正常動作している範囲では、概ね比例する感じです。

ただ、レスポンスタイムが急増してWebアプリが落ち始めるとユーザー増加にブレーキがかかります。例えば同時ユーザー数を6000、秒間10ユーザ増加とかにして(理論値では10分後に最大ユーザー数に到達する)、Webアプリ全体の負荷限界値を探ってみた結果が以下の図(Run #4の部分)。

10分間で6000ユーザーに達するはずが、実際は4910でした。ユーザー数が600を超えたあたりでFailuresが発生はじめて、レスポンスタイムも急増しはじめています。RPSは320前後。今回対象にしたWebアプリでは、この辺が限界のようです。

補足:

このように簡単に負荷テストを実行できます。カスタムヘッダーやPOSTリクエスト、複数のマシンを用いた分散負荷テストなども出来ます。詳細は公式ドキュメントにて。