3
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?

PythonAdvent Calendar 2024

Day 15

【Python】FastAPI vs Flask: 負荷試験による性能比較

Posted at

Pythonで人気のあるWebアプリケーションフレームワーク、FastAPIFlask。どちらも非常に優れたフレームワークですが、その性能には大きな違いがある可能性があります。本記事では、FastAPIとFlaskを使用して同一のAPIを実装し、実際に負荷テストを実施し、得られた結果をもとにパフォーマンスの比較を行います。さらに、負荷テストツールであるlocustのインストール方法とテスト実行方法も詳しく説明します。

目次

  1. はじめに
  2. FastAPIとFlaskの概要
  3. 負荷テストの設計
  4. ライブラリのインストール方法
  5. 実装
  6. 負荷テストの実行方法
  7. 負荷テスト結果の比較
  8. 結論

1. はじめに

Webアプリケーションのパフォーマンスは、特にAPIを提供するサービスにおいて非常に重要です。APIのレスポンスタイムやリクエスト処理能力が、ユーザー体験に直結するためです。Pythonで人気のある2つのWebアプリケーションフレームワークであるFastAPIFlaskの性能を、実際に負荷テストを実施して比較してみましょう。

  • FastAPI: 高速で、非同期処理をサポートする最新のWebフレームワーク。
  • Flask: シンプルで柔軟なWebフレームワーク、特に小規模なアプリケーションに適しています。

本記事では、これら2つのフレームワークを使って同じAPIエンドポイントを実装し、locustというツールを使用して負荷テストを実施し、その結果を比較します。


2. FastAPIとFlaskの概要

FastAPIの特徴

  • 非同期処理のサポート: FastAPIはasync/awaitを使って非同期処理をサポートします。これにより、I/O待機を効率的に処理し、レスポンスが非常に高速です。
  • 型安全性: Pydanticを使用して、リクエストボディやクエリパラメータの型検査や自動バリデーションが行われます。
  • APIドキュメントの自動生成: FastAPIはSwagger UIやReDocを自動で生成し、APIの仕様を簡単に確認できます。

Flaskの特徴

  • シンプルさと柔軟性: Flaskは「マイクロフレームワーク」として非常に軽量であり、シンプルなAPIの作成に最適です。
  • 同期型処理: Flaskは基本的に同期的に動作しますが、geventasyncioを使うことで非同期処理も可能です。
  • 拡張性: Flaskはプラグインや拡張機能が豊富で、プロジェクトに応じて簡単にカスタマイズできます。

3. 負荷テストの設計

テスト目的

FastAPIとFlaskの性能を比較するために、以下のポイントを負荷テストで測定します。

  • レスポンスタイム: APIの応答速度
  • リクエスト数/秒: サーバが処理できるリクエストの量
  • 最大レスポンスタイム: 負荷が高くなった場合の最長の応答時間

テストシナリオ

  • エンドポイント: シンプルなGET /helloエンドポイントを使用します。このエンドポイントはJSONで{"message": "Hello, World!"}というレスポンスを返します。
  • 負荷テストツール: locustを使用してリクエストを送信し、性能を計測します。
  • テスト条件:
    • 最大同時接続数: 1000人
    • テスト時間: 3分
    • ステップ遅延: 1~2秒

4. ライブラリのインストール方法

FastAPI、Flask、および負荷テストツールlocustのインストール方法を解説します。

FastAPIのインストール

FastAPIをインストールするには、以下のコマンドを実行します。

pip install fastapi uvicorn
  • FastAPI: Webフレームワーク本体
  • Uvicorn: ASGIサーバ(FastAPIはASGIベースで動作します)

Flaskのインストール

Flaskをインストールするには、以下のコマンドを実行します。

pip install flask

locustのインストール

負荷テストツールであるlocustをインストールします。

pip install locust

5. 実装

FastAPIとFlaskで同じエンドポイントを実装します。

FastAPIの実装

fastapi_app.py
from fastapi import FastAPI

app = FastAPI()

@app.get("/hello")
async def read_root():
    return {"message": "Hello, World!"}

FastAPIでは非同期関数(async def)を使用して、非同期的にリクエストを処理します。

Flaskの実装

flask_app.py
from flask import Flask

app = Flask(__name__)

@app.route("/hello")
def hello():
    return {"message": "Hello, World!"}

if __name__ == "__main__":
    app.run()

Flaskでは同期的な処理を行いますが、外部ライブラリを使って非同期処理にすることも可能です。


6. 負荷テストの実行方法

負荷テストツールであるlocustを使用して、FastAPIとFlaskの性能を比較します。

負荷テストの作成

locustfile_flask.py
from locust import HttpUser, task, between

# Flaskのテストクラス
class FlaskTest(HttpUser):
    host = "http://127.0.0.1:5000"  # Flaskのホスト(ポート5000で起動)
    wait_time = between(1, 2)  # 1~2秒の間でリクエスト間隔を待機

    @task
    def hello(self):
        self.client.get("/hello")
locustfile_fastapi.py
from locust import HttpUser, task, between

# FastAPIのテストクラス
class FastAPITest(HttpUser):
    host = "http://127.0.0.1:8000"  # FastAPIのホスト(ポート8000で起動)
    wait_time = between(1, 2)  # 1~2秒の間でリクエスト間隔を待機

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

このスクリプトは、/helloエンドポイントにGETリクエストを送信し続けます。FastAPITestクラスがFastAPIサーバに対する負荷テストを実行し、FlaskTestクラスがFlaskサーバに対する負荷テストを実行します。

サーバの起動

それぞれのアプリケーションを別々に起動します。

1. FastAPIのサーバを起動

uvicorn fastapi_app:app --reload --host 0.0.0.0 --port 8000

2. Flaskのサーバを起動

python flask_app.py

負荷テストの実行

locustfile_flask.py``locustfile_fastapi.pyを使って負荷テストを実行します。

locust -f locustfile_[flask/fastapi].py

実行後、ブラウザでhttp://localhost:8089にアクセスする事で、管理画面からテストパラメータ(ユーザー数や発生率)を設定してテストを開始できます。

  • Number of users: 1000(シミュレートするユーザ数)
  • Ramp up: 10(ユーザを10人/秒のペースで増加)
  • Run time: 3m(テスト時間)

スクリーンショット 2024-12-14 2.37.50.png

テストが実行されると、リアルタイムで結果を確認できます。

スクリーンショット 2024-12-14 2.13.25.png


7. 負荷テスト結果の比較

以下は、FastAPIとFlaskの負荷テスト結果です。

Flaskでのリクエスト処理数と失敗したリクエスト数の推移

total_requests_per_second_1734112882.553.png

FastAPIでのリクエスト処理数と失敗したリクエスト数の推移

total_requests_per_second_1734111530.256.png

フレームワーク リクエスト処理数 失敗したリクエスト数
FastAPI 87297 0
Flask 87297 13185

結果の解釈

  • Flaskでは、同時接続数が増加すると、リクエストの処理に失敗する(エラー率が増加する)事がわかります。同時接続数が1000の場合は、15%程のエラー率になっており、非同期でのリクエスト処理をカスタマイズで実装しなければ厳しいかなと思います
  • FastAPIではエラーが一度も出ていないことから、同時接続数が1000台では特にカスタマイズなしで安定的に利用できる事がわかります

8. 結論

どちらを選ぶべきか?

  • FastAPI:

    • 高速で高い並列処理能力が求められる大規模なAPIやリアルタイム性が重要なシステムに最適
    • 非同期処理を活用したい場合や、高速なレスポンスが求められる場合に特に有利
  • Flask:

    • 小規模なプロジェクトや学習用途、シンプルなAPIを作成する場合に最適
    • シンプルさと柔軟性を重視する場合に非常に有用

最終的な選択

  • FastAPIは性能重視のアプリケーションやスケーラビリティが重要な場合に向く
  • Flaskは学習コストが低く、小規模なプロジェクトやAPIに適している

どちらも素晴らしいフレームワークであり、プロジェクトの要件に応じて適切に選択することが重要です。

3
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
3
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?