Gunicornってなんだろう?WSGIってなんだろう?

以下はGunicornについてChatGPTに聞きまくったのと、以下のサイトで勉強して、まとめた内容です。
https://wsgi.readthedocs.io/en/latest/what.html

Djangoとかの書籍買っても(初学者向け)この辺の解説をしてくれる本てなくて「とりあえず、そんなものがあるんだなってことで次に読み進めてください」って感じで省略されちゃう(はぐらかされちゃう)

でも気になるから調べてみた。

イントロダクション

GunicornやWSGIという言葉を初めて聞いた方も多いと思います。特に、DjangoやFlaskなどのPythonを使ったWebアプリケーションを作成し始めたばかりの方にとっては、「これらが何のために必要なのか?」と疑問に思うかもしれません。

まずはWSGIから

WSGI は、Web Server Gateway Interface の略です。Web サーバーが Web アプリケーションと通信する方法、および Web アプリケーションを連鎖させて 1 つのリクエストを処理する方法を記述した仕様です。

https://wsgi.readthedocs.io/en/latest/what.html

PythonのWebアプリケーションとWebサーバーを繋ぐための「標準的な規格(プロトコル)」です。要するに、WSGIはPythonのアプリとWebサーバーが「会話」するための共通の言語を提供してくれる役割を担っています。

Webサーバー(NginxやApacheなど)は、HTTPリクエストを受け取る仕事をしていますが、直接Pythonアプリケーションを実行する能力はありません。ここでWSGIが重要になります。WSGIがあることで、Webサーバーが受け取ったHTTPリクエストをPythonアプリケーションが理解できる形に変換し、逆にPythonアプリが返すレスポンスをWebサーバーが理解できる形に変換してくれるのです。

これにより、Pythonで作ったWebアプリケーション(例:DjangoやFlask)をWeb上で動かすことができるようになります。

要は通訳です。

Webサーバー(Nginx)は「HTTP」という言語を話し、Pythonアプリケーションは「Python」という言語を話します。それぞれが別々の言語を話しているので、直接やり取りをすることはできません。しかし、WSGIはその2つの言語を理解しているので、両者がスムーズにコミュニケーションできるようにしてくれる

ちなみに
サーバーでも、Pythonモジュールでも、フレームワークでも、APIでも、その他のソフトウェアでもありません。サーバーとアプリケーションが通信するためのインターフェース仕様にすぎません。
クライアントからのリクエストを受信し、それをアプリケーションに渡し、アプリケーションから返された応答をクライアントに送信するだけです。それ以外は何も行いません

Gunicornとは何か?

Gunicornの意味

Gunicorn(Green Unicornの略)は、Pythonで書かれたWSGIサーバーです。WSGIがPythonアプリケーションとWebサーバーの間での「通訳」の役割を果たすことはわかりましたが、実際にその通訳を動かすためには「WSGIサーバー」が必要です。Gunicornは、このWSGIサーバーの1つです。

WSGIサーバーは、Pythonアプリケーションを実行し、Webサーバー(例えばNginxなど)からのリクエストを受け取って、アプリケーションを動かし、その結果をWebサーバーに返します。

Gunicornは特にDjangoやFlaskなどのWebアプリケーションフレームワークと一緒に使われることが多く、PythonのWebアプリケーションを本番環境で動かすために一般的に使用されます。

Gunicornの役割

Gunicornは、以下の役割を果たします。

  1. リクエストの処理
    Gunicornは、Webサーバー(例:Nginx)から送られてきたリクエストを受け取ります。そして、そのリクエストをPythonアプリケーション(DjangoやFlaskなど)が理解できる形で処理します。

  2. 並行処理
    Gunicornは、1つのリクエストだけを処理するのではなく、同時に複数のリクエストを処理することができます。これを実現するために、Gunicornは「ワーカー」という仕組みを使います。

  3. スケーラビリティ
    アクセスが増えるにつれて、Gunicornは追加のワーカーを生成することで、効率よくリクエストを処理できます。この仕組みのおかげで、負荷が増えたときでもスムーズに処理が行われます。

GunicornとWebサーバ(例としてNginx)との連携

Gunicornは通常、NginxのようなWebサーバーと一緒に使われます。今回はとりあえずNginxを例に解説します。
Nginxは主に以下の役割を担います。

  • 静的ファイル(画像やCSS、JavaScriptなど)の提供

  • 負荷分散やプロキシの役割

対してGunicornは動的なリクエスト(例えば、データベースとやり取りして生成されるコンテンツ)を処理します。一方で、Nginxはその処理結果をクライアントに返す役割を担います。

一旦ここまでをまとめる

  1. WSGIとWebサーバの違い:

    • Webサーバ(例:Nginx、Apache): クライアントからのHTTPリクエストを受け取り、静的ファイルを提供したり、動的コンテンツの要求を適切なバックエンドに転送したりします。

    • WSGIサーバ(例:Gunicorn): Pythonアプリケーションを実行し、WSGI仕様に従ってWebサーバとアプリケーション間の通信を処理します。

  2. 例としてNginxとGunicornの関係:

    • Nginx: フロントのWebサーバとして機能し、静的ファイルの提供や負荷分散を担当します。

    • Gunicorn: WSGIサーバとして、NginxとPythonアプリケーションの間に位置し、アプリケーションコードを実行します。

ここまでを踏まえてシステム設計をしてみて理解する

  1. Webサーバー(例:Nginx)をフロントに配置
    通常、NginxのようなWebサーバーがフロントエンドとして配置されます。Nginxはクライアントからのリクエストを受け取り、それが静的コンテンツ(画像、CSS、JavaScriptなど)の場合は、そのままクライアントにレスポンスを返します。

  2. 動的コンテンツはGunicornにプロキシする
    クライアントがリクエストしたページが動的なものである場合(例えば、データベースから情報を取得してページを生成するなど)、NginxはそのリクエストをGunicornにプロキシ(中継)します。GunicornはPythonアプリケーションを使ってリクエストを処理し、その結果をNginxに返します。Nginxはその結果をクライアントに返す役割を担います。

この設計の概要

  • 効率的な静的コンテンツの提供
    Nginxは静的コンテンツ(HTML、CSS、画像など)を非常に効率よく処理できます。Gunicornに動的コンテンツのみを処理させることで、システム全体の効率が向上します。Nginxはリソースをほとんど消費せず、クライアントに高速に静的コンテンツを配信することができます。

  • 動的コンテンツのスケーラビリティ
    Gunicornは複数の「ワーカー」プロセスを使って動的リクエストを処理します。これにより、同時に多数のリクエストを処理することができ、大量アクセス時でもシステムが安定して動作するようになります。Gunicornを単独で使うのではなく、Nginxと組み合わせることで、処理の分担がはっきりし、全体のパフォーマンスが向上します。


NginxとGunicornのインストール場所について

システム設計の際、NginxとGunicornをどこにインストールするべきかについては、主に2つの選択肢があります。それぞれのメリットとケースごとの適用シナリオについても解説します。

1. NginxとGunicornを同じ物理マシンにインストールする

一般的には、NginxとGunicornは同じマシンにインストールされることが多いです。この構成は、シンプルで管理がしやすく、中規模程度のトラフィックを処理するアプリケーションには十分対応できます。

  • メリット

    • 設定が簡単で、システム全体の管理がしやすい。

    • 物理マシンを1つだけ用意すれば良いので、コストが抑えられる。

    • NginxとGunicorn間の通信はローカルで行われるため、ネットワーク遅延がほぼなく、効率的に動作する。

  • 適したケース

    • 小〜中規模のアプリケーション。

    • 単一のVM(仮想マシン)でアプリケーションをデプロイしたい場合。

    • コストを抑えつつ、シンプルなシステム設計が求められる場合。


2. NginxとGunicornを別々のマシンにインストールする

大規模なトラフィックを処理する必要がある場合や、負荷を分散したい場合には、NginxとGunicornを異なる物理マシンにインストールするという選択肢もあります。

  • GunicornをPythonアプリケーションが動くマシンにインストールする GunicornはPythonアプリケーションを実行するWSGIサーバーです。そのため、Pythonアプリが動作するマシンにGunicornをインストールする必要があります。この場合、Nginxはフロントエンドに配置され、リクエストをGunicornの動いている別のサーバー(マシン)にプロキシします。

  • メリット

    • スケーラビリティが高い。NginxとGunicornをそれぞれ異なるマシンで運用することで、負荷分散が可能。

    • 可用性が高まる。1つのマシンに障害が発生しても、他のマシンが動作し続ける。

    • 大規模なトラフィックにも対応できる。複数のPythonアプリケーションマシンにGunicornを配置してリクエストを分散することができる。

  • 適したケース

    • 大規模なトラフィックが予想されるアプリケーション。

    • サービスの可用性を高めたい場合(例えば、複数の地域にサーバーを分散する場合)。

    • 負荷を分散し、NginxとGunicornに別々の役割を明確にしたい場合。


番外編

ワーカー

  1. ワーカー(Worker):

    • ワーカーは独立したプロセスです。

    • 各ワーカーは、アプリケーション(この場合はDjango)の完全なコピーを実行します。

    • ワーカーは並行して動作し、それぞれが独立してリクエストを処理できます。

  2. プロセス vs スレッド:

    • プロセス: オペレーティングシステムによって管理される、独立したプログラム実行の単位です。各プロセスは独自のメモリ空間を持ちます。

    • スレッド: 1つのプロセス内で実行される軽量な実行単位です。同じプロセス内のスレッドはメモリを共有します。

  3. Gunicornのワーカーモデル:

    • Gunicornは通常、マルチプロセスモデルを使用します。

    • 各ワーカーは別々のプロセスとして実行されます。

    • これにより、1つのワーカーが問題を抱えても、他のワーカーには影響しません。

  4. プロセスベース vs スレッドベース:

    • Gunicornのデフォルトは「同期ワーカー」で、これはプロセスベースです。

    • 一方、一部のアプリケーションサーバーはスレッドベースのモデルを使用します。

  5. なぜプロセスベースなのか:

    • Python の GIL(Global Interpreter Lock)の制約を回避できます。

    • プロセス間のメモリ分離により、安定性が向上します。

    • 各ワーカーが独立しているため、1つのワーカーの問題が他に波及しにくいです。

  6. デメリット:

    • プロセスはスレッドよりもメモリを多く使用します。

    • プロセス間の切り替えは、スレッド間の切り替えよりもコストがかかります。

簡単な例え: ワーカーは、レストランの厨房で働くコックさんのようなものです。各コックさん(ワーカー)は独立して注文(リクエスト)を処理できます。コックさんを増やせば(ワーカー数を増やせば)、同時に処理できる注文の数が増えます。

Python以外の言語でのWSGI的なもの

WSGIはPythonのために作られた特定の規格であり、他のプログラミング言語にはそれぞれに応じた似たようなインターフェースやゲートウェイの仕組みが存在します。つまり、他の言語にはWSGIそのものは存在しませんが、同様の役割を果たす技術やインターフェースが各言語で採用されています。以下は、各言語でWSGIに相当する技術です。

他の言語におけるWSGIに相当するインターフェース

  1. Java: Servlet API

    • Javaでは、Webアプリケーションを構築するために「Servlet API」が標準として使われています。Servletは、JavaベースのWebアプリケーションとWebサーバー(TomcatやJettyなど)とのやり取りを標準化した仕組みで、WSGIと似た役割を果たします。

    • Servlet APIの役割: JavaアプリケーションがHTTPリクエストを処理する際、Servlet APIがそのインターフェースとなります。

  2. Ruby: Rack

    • RubyのWebアプリケーションでは、「Rack」というインターフェースが広く使われています。Rackは、RubyのWebサーバー(PumaやUnicornなど)とRubyアプリケーションを繋ぐための標準化されたインターフェースです。

    • Rackの役割: HTTPリクエストを受け取り、それをRubyアプリケーションに渡し、レスポンスを生成して返すという点で、WSGIに非常に似ています。

  3. PHP: PHP-FPM(FastCGI Process Manager)

    • PHPはもともとWeb向けに作られた言語であり、WSGIのようなゲートウェイインターフェースは必要ありませんが、PHP-FPM(FastCGI Process Manager)がWebサーバーとのやり取りを最適化するために使われています。これは、PHPアプリケーションが効率的に動作するように管理します。

    • PHP-FPMの役割: NginxやApacheのようなWebサーバーとPHPのアプリケーションを効率的に繋げる仕組みとして使われます。

  4. Node.js: Connect/Express

    • Node.jsでは、「Connect」や「Express」のようなミドルウェアフレームワークが使用されています。これらはNode.jsのWebサーバー(HTTPサーバー)とNode.jsアプリケーションをつなぐ役割を持っています。

    • Express/Connectの役割: これらのフレームワークは、Node.jsアプリケーションがリクエストを処理するための標準的なインターフェースを提供します。WSGIに似て、リクエストを処理し、レスポンスを返すフローをシンプルにします。

  5. Go: net/httpパッケージ

    • Go言語には「net/http」という標準ライブラリがあり、これを使ってHTTPサーバーを構築し、リクエストとレスポンスの処理を行います。Goの設計思想として、外部のWebサーバーに依存することなく、自前でHTTPサーバーを持つことができるため、WSGIのようなインターフェースは不要です。

    • net/httpパッケージの役割: Goアプリケーション内で直接リクエストを処理し、レスポンスを返すことができます。

  6. C# (.NET): OWIN (Open Web Interface for .NET)

    • C#やASP.NETには「OWIN(Open Web Interface for .NET)」というインターフェースがあります。OWINは、.NETアプリケーションとWebサーバー(IISなど)を繋ぐための標準化されたインターフェースです。

    • OWINの役割: OWINは、WebサーバーからHTTPリクエストを受け取り、それを.NETのアプリケーションに渡すための仕組みで、WSGIと同様の目的を果たします。


この記事が気に入ったらサポートをしてみませんか?