10
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

本記事は セゾンテクノロジー Advent Calendar 2025 2 日目の記事です。

概要

  • Web サイトの性能テストを行いたい
    • どれくらいの負荷に耐えられるのか?
  • python のライブラリである locust を利用して計測してみる

実施するテスト例

特定の Web サイトに同時アクセスして正常にコンテンツが返ってくるどうか
どれだけの同時アクセスに耐えられるか試す

テストプログラム作成

  1. テスト用の Web サイト準備
    • docker で nginx の起動する例
    • docker run -p 8000:80 nginx を実行。http://localhost:8000/ で表示可能
  2. python と uv をセットアップしておく
  3. pyproject.toml ファイルを用意しての uv sync、または uv add locust などでインストール
    project.toml
    [project]
    name = "performance-test"
    version = "0.1.0"
    requires-python = ">=3.11"
    dependencies = [
        "locust>=2.31.8",
        "python-dotenv>=1.0.0",
    ]
    
  4. Web サイトにアクセスしてコンテンツが返されるか?のテストを python で作成する。
    locust が用意する client を使って Web サイトへの処理を記述する。
    同時アクセスについてはここで記述しない。
    locus_hello.py
    from locust import HttpUser, task, constant
    import traceback
    import os
    import logging
    
    logger = logging.getLogger(__name__)
    
    class HelloUser(HttpUser):
        wait_time = constant(1)
        host = "http://localhost:8000/"
        
        @task
        def load_top_page(self):
            try:
                with self.client.get("/", catch_response=True, timeout=30) as response:
                    # ステータスコードの検証
                    if response.status_code != 200:
                        error_msg = f"ステータスコードが200ではありません: {response.status_code}"
                        if hasattr(response, 'text'):
                            error_msg += f"\nレスポンス内容: {response.text[:500]}"
                        response.failure(error_msg)
                    else:
                        logger.info(f"レスポンス内容: {response.text[:500]}")
                        # コンテンツの文字列検証
                        if "Welcome to nginx!" in response.text:
                            response.success()
                        else:
                            response.failure(f"コンテンツに「Welcome to nginx!」が含まれていません\nレスポンス内容(先頭500文字): {response.text[:500]}")
            except Exception as e:
                error_detail = f"リクエスト失敗: {type(e).__name__}: {str(e)}\n{traceback.format_exc()}"
                print(error_detail)
                self.environment.events.request.fire(
                    request_type="GET",
                    name="/",
                    response_time=0,
                    response_length=0,
                    exception=e,
                )
    
    

テストの実行

  1. uv run locust -f .\locus_hello.py を実行
  2. ブラウザで http://localhost:8089 にアクセスすると locust の画面が表示される
    image.png
  3. 最大同時接続数、1秒ずつにどれくらい接続ユーザ数を増やすかを入力して START! をクリックする
    • Number of users (peak concurrency): 最大同時接続数
    • Ramp up (users started/second): 増やしていく接続ユーザ数
  4. 起動したら CHARTS タブをクリック
  5. 一番上のグラフの赤い Failures が増えてきたら STOP する
    • 同時接続が 100 を超えたあたりから失敗が増えている
      image.png
  6. 内容を解析したり、DOWNLOAD DATA から必要な情報をダウンロードする

まとめ

  • 簡単ですが locust の紹介でした
  • GET だけではなく POST もできるので任意のリクエストを投げることもできます
    • 例: チャットボットアプリでどれだけ同時にメッセージを送信してレスポンスが返ってくるか
  • Web サイトの性能が把握できたらユニットテストとして CI から定期実行するという運用も可能になります
    • 性能が劣化した場合などにすぐ気がつける
  • ぜひお試してください!
10
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?