Open8

Pythonでのアプリケーション実行時に出てくるUvicorn, Gunicornや、workerについてまとめる

KeitaUenishiKeitaUenishi

WSGIとは

概要

Web Server Gateway Interface の略。
同期的なインターフェースであり、リクエストを逐次処理で実行する。

Web Server Gateway Interface (WSGI; ウィスキー[1][2]) は、プログラミング言語Pythonにおいて、WebサーバとWebアプリケーション(あるいはWebアプリケーションフレームワーク)を接続するための、標準化されたインタフェース定義である。また、WSGIから着想を得て、他の言語でも同様のインタフェースが作られた。

引用: https://ja.wikipedia.org/wiki/Web_Server_Gateway_Interface

ほぼWikipediaそのままになるが、Pythonで書かれたWebアプリケーションは元々さまざまな方法で実装されていた。そのため、PythonにおけるWebアプリケーションとWebサーバーを接続する標準仕様を定めるものとしてWSGIが考案された。

これにより、WSGIに対応したWebアプリケーションやフレームワークは、任意のサーバー上で運用できるようになる。

WSGIには二つの側 — サーバ側とアプリケーション側が存在する。WSGIは、リクエスト情報・レスポンスヘッダ・レスポンス本文を、両者の間でどのようにやりとりするかをPythonのAPIとして定義している。

Webサーバにリクエストが来ると、次のような流れでやりとりが行なわれる:

  1. サーバ側が、クライアントからリクエストを受ける。
  2. サーバ側は、アプリケーション側がエントリポイントとして提供するcallableオブジェクト(関数やクラスインスタンスなど call が定義されたオブジェクト)を呼び出して、その引数として環境変数と1つのコールバック用callableオブジェクトを渡す。
  3. アプリケーション側は、このコールバック用callableオブジェクトを呼び出すことでステータスコードとレスポンスヘッダをサーバ側に伝え、さらに本文を生成するiterableオブジェクト(イテレータやリストなど)を戻り値として返す。
  4. サーバ側は、これらを用いてクライアントへのレスポンスを生成する。

WSGIはミドルウェアの考え方も提供できる。WSGIミドルウェアは、サーバ側とアプリケーション側のWSGIインタフェースを実装しているため、WSGIサーバとWSGIアプリケーションの"中間に"挿入できる。ミドルウェアはサーバーの視点からはアプリケーションとして振る舞い、アプリケーションの視点からはサーバーとして振る舞う。

引用: https://ja.wikipedia.org/wiki/Web_Server_Gateway_Interface

KeitaUenishiKeitaUenishi

WSGIの仕様に則っている著名なFrameWorkとしては

  • Django
  • Flask
    などがある

これらのWebフレームワークで作ったWebアプリケーションは、WSGIサーバーで動作させることができる。

KeitaUenishiKeitaUenishi

ASGIとは

概要

Asynchronous Server Gateway Interfaceの略称。

ASGI(Asynchronous Server Gateway Interface)は、WSGIの精神的後継であり、非同期対応のPythonウェブサーバー、フレームワーク、アプリケーション間の標準インターフェースを提供することを目的としている。

WSGIが同期Pythonアプリのための標準を提供したのに対し、ASGIはWSGIの後方互換性のある実装と複数のサーバーとアプリケーションフレームワークで、非同期と同期の両方のアプリのための標準を提供する。

引用: https://asgi.readthedocs.io/en/latest/

KeitaUenishiKeitaUenishi

以下はほぼASGIのドキュメントそのまま要約。

ASGIは、Webサーバー、フレームワーク、アプリケーション間の互換性のための長年のPython標準であるWSGIの精神的な後継です。
WSGIは、PythonのWeb空間でより多くの自由と革新を可能にすることに成功し、ASGIのゴールは、非同期Pythonの土地に向かってこれを継続することです。

なぜWSGIをアップグレードしないのか」と尋ねるかもしれません。 WSGIの単一呼び出し可能なインターフェイスは、WebSocketのような、より複雑なWebプロトコルには適していないというのが、大抵の場合です。

WSGIアプリケーションは、リクエストを受け取り、レスポンスを返す、単一の同期呼び出し可能なものです。これは、ロングポールのHTTPやWebSocketコネクションで得られるような、長時間のコネクションを許しません。

この callable を非同期にしたとしても、リクエストを提供するパスは1つしかないので、複数の受信イベント(WebSocket フレームの受信など)を持つプロトコルはこれをトリガーできない。

その上で、ASGIは何をするのか?

ASGIは、単一の非同期呼び出し可能な構造になっています。 ASGIは、特定の接続の詳細を含むdictであるscope、アプリケーションにイベント・メッセージをクライアントに送信させる非同期 callableであるsend、アプリケーションにクライアントからのイベント・メッセージを受信させる非同期 callableであるreceiveを取ります。

これは、各アプリケーションに複数の受信イベントと送信イベントを許可するだけでなく、アプリケーションが他のこと(Redisキューのような外部トリガーのイベントをリッスンするなど)ができるように、バックグラウンドのコルーチンを許可します。

引用: https://asgi.readthedocs.io/en/latest/introduction.html

ここで理解したこととしては、

  • WSGIは同期的な処理が前提
  • ASGIは名前のとおり、非同期処理をサポートするためのもの
    • リアルタイムのアプリケーションや大量の同時接続を同時に処理できるようになる
KeitaUenishiKeitaUenishi

Gunicornとは

正式名称はGreen Unicorn。

  • WSGI準拠のPythonアプリケーションを実行するためのサーバー
  • 同期的アプリケーションに向いており、多くのPython Webフレームワークと互換性がある

Gunicorn 'Green Unicorn' はUNIX用のPython WSGI HTTPサーバーです。 RubyのUnicornプロジェクトから移植されたプレフォークワーカーモデルです。 Gunicornサーバーは、様々なウェブフレームワークと幅広く互換性があり、シンプルに実装されており、サーバーリソースの消費が少なく、かなり高速です。

  • WSGI、Django、Paster をネイティブサポート
  • ワーカープロセスの自動管理
  • Python の簡単な設定
  • 複数のワーカ設定
  • 拡張性のための様々なサーバフック
  • Python 3.x >= 3.7 と互換性あり

また、リクエスト処理中にアプリケーションコードが長時間休止する必要がある場合は、Eventlet や Gevent をインストールするとよいでしょう。 どのような場合に代替ワーカーを検討するかについては、設計ドキュメントを参照してください。

引用: https://docs.gunicorn.org/en/stable/

KeitaUenishiKeitaUenishi

Uvicornとは

UvicornはPython用のASGI Webサーバー実装です。 つい最近まで、Pythonには非同期フレームワーク用の最小限の低レベルサーバー/アプリケーションインターフェースがありませんでした。 ASGI仕様はこのギャップを埋め、すべての非同期フレームワークで使える共通のツールのセットを作り始められることを意味します。
Uvicornは現在HTTP/1.1とWebSocketをサポートしています。

非同期処理が得意で、リアルタイムなアプリケーションや非同期タスクの処理が効率的。
FastAPIはASGIを前提とした非同期フレームワークとして開発されている。

「uvicorn 読み方」で調べるといろんな読み方が出てくる…

  • アッバーコーン
  • ユーブイアイコーン
  • ユビコーン

uvicorn(アッバーコーン)は、Python製のASGI(Asynchronous Server Gateway Interface)サーバーだ。ASGIは、非同期処理をサポートするWebアプリケーションフレームワークに対する標準的なインターフェースだ。
FastAPIのようなASGIフレームワークで開発されたWebアプリケーションを実行するために、uvicornを使用することが一般的だ。uvicornは、非同期処理に特化しており、高速でスケーラブルなWebアプリケーションを実現することができる。

引用: https://zenn.dev/nameless_sn/articles/fastapi_tutorial_for_rest#uvicorn

KeitaUenishiKeitaUenishi

FastAPIのドキュメント

GunicornとUvicorn

GunicornWSGI標準のアプリケーションサーバーです。このことは、GunicornはFlaskやDjangoのようなアプリケーションにサービスを提供できることを意味します。Gunicornそれ自体はFastAPIと互換性がないですが、というのもFastAPIは最新のASGI 標準を使用しているためです。

しかし、Gunicornはプロセスマネージャーとして動作し、ユーザーが特定のワーカー・プロセスクラスを使用するように指示することができます。するとGunicornはそのクラスを使い1つ以上のワーカー・プロセスを開始します。

引用: https://fastapi.tiangolo.com/ja/deployment/server-workers/#gunicornuvicorn