Gunicorn を使用した Python アプリケーションのデプロイ
最終更新日 2024年03月13日(水)
Table of Contents
受信 HTTP リクエストを並列処理する Web アプリケーションの方が、一度に 1 つのリクエストしか処理しない Web アプリケーションより dyno リソースをより効率的に使用します。このため、本番環境のサービスを開発して実行するときは常に、並列リクエスト処理をサポートする Web サーバーを使用することをお勧めします。
Django と Flask の各 Web フレームワークは便利なビルトイン Web サーバーを備えていますが、これらのブロッキングサーバーは一度に 1 つのリクエストしか処理しません。Heroku でこれらのサーバーを使用してデプロイを行うと、dyno リソースの利用効率とアプリケーションの応答性が低下します。
Gunicorn は、WSGI アプリケーション用の純粋な Python HTTP サーバーです。単一 dyno 内で複数の Python プロセスを実行することによって、任意の Python アプリケーションを並列して実行できるようにします。Gunicorn は、パフォーマンス、柔軟性、設定のシンプルさの絶妙なバランスを提供します。
このガイドでは、Gunicorn Web サーバーを使用して新しい Python アプリケーションを Heroku にデプロイする方法について説明します。Heroku の基本的なセットアップと知識については、「Getting Started with Python」(Python スターターガイド) を参照してください。
いつものように、本番環境アプリケーションにデプロイする前に、ステージング環境で設定変更をテストします。
アプリケーションへの Gunicorn の追加する
まず、pip
を使用して Gunicorn をインストールします。
$ pip install gunicorn
必ず、requirements.txt
ファイルにも gunicorn
を追加してください。
次に、Gunicorn を使用するためにアプリケーションの Procfile
を修正します。次に示すのは、「Heroku スターターガイド (Python)」で作成した Django アプリケーション用の Procfile
の例です。
Procfile
web: gunicorn gettingstarted.wsgi
基本設定
Gunicorn は各 dyno 内で複数のシステムプロセスをフォークして、Python アプリがスレッドセーフでなくても複数の並列リクエストをサポートできるようにします。Gunicorn の用語では、これらはワーカープロセスと呼ばれます (独自の dyno で実行される Heroku ワーカープロセスと混同しないようにしてください)。
システムプロセスをフォークするごとに消費メモリが増加します。これにより、1 つの dyno で実行できるプロセスの数が制限されます。一般的な Django アプリケーションのメモリフットプリントでは、eco
、basic
、または standard-1x
dyno で 2 ~ 3 個の Gunicorn ワーカープロセスが実行されることが想定されます。アプリケーション固有のメモリ要件によっては、この想定から外れることが許容される場合があります。
この設定のための環境設定を行うことをお勧めします。WEB_CONCURRENCY
環境変数が設定されている場合、Gunicorn は自動的にこの環境変数を優先します。
$ heroku config:set WEB_CONCURRENCY=3
WEB_CONCURRENCY
環境変数は、プロセスの dyno サイズに基づいて、Heroku によって自動的に設定されます。この機能は、アプリケーションのための適切な開始点になることを目的にしています。プロセスのメモリ要件を把握し、それに応じてこの環境設定を調整することをお勧めします。
スループット最大化のための Python アプリケーションのチューニングについての詳細は、「Python アプリケーションの並列性の最適化」を参照してください。
Procfile
web: gunicorn hello:app
Heroku Labs の log-runtime-metrics 機能は、実行中の dyno の負荷およびメモリ使用量を可視化するためのサポートを追加します。有効にすると、heroku logs
コマンドを使用してアプリケーションのメモリ使用量を監視できます。
高度な設定
アプリの事前ロード
メモリの制約がある場合やアプリの起動時間が低速な場合は、preload
オプションを有効にすることを検討してください。有効にすると、ワーカープロセスがフォークされる前にアプリケーションコードが読み込まれます。
web: gunicorn hello:app --preload
詳細については、事前ロードに関する Gunicorn のドキュメントを参照してください。
ワーカーのタイムアウト
デフォルトでは、ワーカーが過去 30 秒以内に何の処理も完了していない場合、Gunicorn によって暗黙的にワーカーが再起動されます。リクエストの絶え間ない受信フローにアプリケーションが迅速に応答することを期待する場合は、タイムアウト設定値を下げてみてください。
$ gunicorn hello:app --timeout 10
詳細については、ワーカーのタイムアウトに関する Gunicorn のドキュメントを参照してください。
最大リクエストリサイクル
アプリケーションでメモリリークが発生している場合、指定された数のリクエストがワーカーで処理された後、ワーカーを暗黙的に再起動するように Gunicorn を設定できます。これは、メモリリークの影響を限定するために役立つ便利な方法となる可能性があります。
$ gunicorn hello:app --max-requests 1200
詳細については、最大リクエスト数に関する Gunicorn のドキュメントを参照してください。