Flaskアプリケーションのデプロイ方法Flask + Gunicorn + Nginx

1.なぜFlask + Gunicorn + Nginxなのか

Flask + Gunicorn + Nginxは、最も一般的に使用されているFlaskデプロイメントソリューションです。なぜこの組み合わせを使用するのか疑問に思ったことはありませんか?

1.1なぜですか?

FlaskはWebフレームワークであり、Webサーバーではありません。Flaskによって直接プルアップされるWebサービスは、開発環境に限定されます。本番環境は十分に安定しておらず、多数のリクエストの同時実行に耐えることができません。ティー環境では、Gunicorn、Nginx、Apacheなどの各リクエストを処理するためにサーバーソフトウェアが必要であり、Gunicorn + Nginxの組み合わせには多くの利点があります。一方で、Nginxに基づくGunicornサービスを転送します。実稼働環境でのGunicornサービスの欠陥。サービスに加えて、Webサイトにはホストする必要のある静的ファイルも多数あります。これはNginxの長所であり、Gunicornが適していないものでもあります。したがって、Flaskに基づくWebサイトをデプロイするときは、GunicornとNginxを使用することをお勧めします。

1.2他に何かありますか?

1. Gunicornサービスを転送するためにNginxが必要なのはなぜですか?

Nginxは強力であり、Nginxを使用することには多くの利点があります。ただし、Nginxを使用してGunicornサービスを転送することは、サーバーでの「クライアントの動作が遅い」ことによって引き起こされるパフォーマンス低下の問題の解決に重点を置いています。さらに、インターネットにHTTPサービスを展開する場合も同様です。 、「高速クライアント応答」、SSL処理、および高い同時実行性の問題はすべてNginxで解決できることも考慮する必要があります。したがって、Gunicornサービスの上にNginxリバースプロキシのレイヤーを追加することは、複数の目的に役立つ展開ソリューションです。

2.「クライアントの動作が遅い」ためにサービスパフォーマンスが低下する問題があるのはなぜですか。

サーバーとクライアント間の通信は、要求、要求処理、応答の3つの部分に分けられます。つまり、クライアントはサーバーへの要求を開始し、サーバーは要求に応答して処理し、要求結果をクライアントに返します。 。これらの3つのプロセス。

通常、リクエスト処理部分はサーバーのパフォーマンスに関するサーバーの計算であり、処理はより効率的で安定していますが、リクエストとレスポンスの部分はより影響力のある要素を持っています。これらの3つのプロセスが同期処理の同じプロセス要求部分と応答部分に時間がかかる場合、コンピューティングリソースが占有され、時間内に解放できないため、コンピューティングリソースの使用効率が低下し、サーバーの処理能力が低下します。

上記の「遅いクライアントの動作」は、要求(または応答)の時間のかかる部分を指します。Gunicornは、たまたま上記の3つのプロセスを同じプロセスに入れます。「遅いクライアントの動作」が発生すると、効率は非常に低くなります。

Gunicornはプリフォークソフトウェアであり、負荷分散やサービス間通信などの低遅延通信に非常に効果的です。ただし、プリフォークシステムの欠点は、各通信がプロセスを排他的に占有することです。サーバーで使用可能なプロセスよりも多くの要求がサーバーに送信されると、サーバー上にプロセスがなくなるため、応答効率が低下します。新しい要求に応答するサーバー側。

Webサイトまたはサービスの場合、要求と応答の遅延は制御できないため、待ち時間の長いクライアント要求の処理を検討する必要があります。これらのリクエストはサーバー側のプロセスを占有します。低速クライアントがサービスと直接通信する場合、低速クライアント要求がプロセスを占有するため、新しい要求の処理に使用できるプロセスの数が減少します。すべてのプロセスを占有する低速クライアント要求が多数ある場合、新しい要求は後でのみ待機できます。プロセスが解放されると、応答が返されます。さらに、アプリケーションがより高い同時実行性を必要とする場合、サーバーとクライアント間の通信はより効率的である必要があり、非同期通信は同期通信よりも効果的です。

Nginxなどの非同期サーバーソフトウェアは、メモリとCPUのオーバーヘッドが非常に少ない状態で多数のリクエストを処理するのに適しています。同時に多数のクライアント要求を処理するのが得意であるため、遅いクライアント要求はそれらにほとんど影響を与えません。Nginxに関する限り、通常のサーバーハードウェア条件下では、数万のリクエストを同時に処理するのは簡単です。

したがって、リクエストを処理するためにプレフォークサービスの前でNginxをブロックすることは良い選択です。Nginxはクライアントリクエストに非同期で高い同時実行性で応答できます(遅いクライアントリクエストはNginxにほとんど影響を与えません)。Nginxはリクエストを受信するとすぐに処理のためにGunicornサービスに転送し、Nginxは結果をクライアントに送り返します。応答の形式。終了。このようにして、サーバーとクライアント間の通信全体が、Gunicornのみを介した元の同期通信から、NginxとGunicornに基づく非同期通信に変更され、通信効率と同時実行性が大幅に向上しました。

ウェブサイトについては、上記の状況に加えて、さまざまな静的ファイルのホスティングも考慮する必要があります。静的ファイルには、CSS、JavaScript、その他のフロントエンドファイルだけでなく、画像、ビデオ、さまざまなドキュメントも含まれるため、静的ファイルはより大きくなるか、より頻繁に呼び出される可能性があります。静的ファイルのホスティング機能は、あらゆる種類のファイルを確保することです。静的パフォーマンス。通常のロード、プレビュー、またはダウンロードは、実際には、応答の長い時間のかかる「遅いクライアント動作」です。Gunicornを使用して静的ファイルをホストすると、Gunicornの応答効率にも深刻な影響があります。これはまさにNginxの得意分野であるため、静的ファイルのホストはNginxで処理する必要があります。

 

2. FlaskWebサイトをデプロイする方法

前のセクションの説明と組み合わせると、FlaskWebサイトを展開する方法も非常に明確です。

  1. サーバーソフトウェア(Gunicornなど)を使用して、Flaskで記述されたアプリケーションをプルアップします
  2. Nginxを使用して、前の手順でプルアップしたアプリケーションのリバースプロキシを作成します
  3. ウェブサイトに含まれる静的ファイルは、ファイルホスティングにNginxを使用します

一般的なサーバーソフトウェアはGunicornとuWSGIです。Gunicornは使いやすく効率的であるため、Gunicornを使用してFlask Webサイトをプルアップするのは非常に簡単です。したがって、Gunicornは通常FlaskWebサイトの展開に使用されます。(さらに、Gunicornは純粋なPythonで記述されており、pipで直接インストールできるため、Gevinは個人的にGunicornも気に入っていますが、uwsgiはシステムに追加の依存関係をインストールする必要があります。これは、dockerで使用すると特に簡単です。

静的ファイルのホスティングについては、通常、開発フェーズで静的ファイルホスティングを実装するためにFlaskフレームワークが使用されるため、Gunicornを使用してFlask Webサイトをプルアップすると、WebサイトはGunicornに基づくファイルホスティング機能を実装します。 Nginxの静的ファイルホスティングURLを使用すると、Gunicornホスティングと整合性のあるファイルパスとして直接構成できるため、開発と展開のロジックが簡素化されます。さらに、NginxはGunicornよりも1層高いため、クライアントが静的ファイルの場合、Nginxは直接応答を返します。サーバーの効率に影響を与えるようにGunicornに要求することを心配する必要はありません。

2.1 Gunicorn

GunicornがFlaskWebサイトを展開する方法、公式のFlaskファイルまたはGunicornファイルを確認するだけで、通常は次のようなコマンド行を実行するだけです。

/usr/local/bin/gunicorn -w 2 -b :4000 manage:app

2.2 Nginx

Nginxをリバースプロキシとして使用し、静的ファイルをホストすることも非常に簡単です。使用できるデモを提供するためにここにいます。その他の再生方法については、Nginxのドキュメントを参照してください。

server {
    listen 80;

    server_name localhost;

    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        proxy_pass         http://localhost:8000/;
        proxy_redirect     off;

        proxy_set_header   Host             $http_host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    }

    location /media  {
        alias /usr/share/nginx/html/media;  
    }

    location /static  {
        alias /usr/share/nginx/html/static;  
    }
}

その中で、リバースプロキシの構成は次のとおりです。

    location / {
        proxy_pass         http://localhost:8000/;
        proxy_redirect     off;

        proxy_set_header   Host             $http_host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    }

静的ファイルホスティングの構成は次のとおりです。

    location /media  {
        alias /usr/share/nginx/html/media;  
    }

    location /static  {
        alias /usr/share/nginx/html/static;  
    }

ここでは、2つのフォルダー内のファイルを管理しました。

 

3.DockerベースのFlaskWebサイトのデプロイ

Dockerには、一度デプロイしてどこでも実行できるという利点があります。実際には、上記の従来のデプロイ方法をDockerイメージにカプセル化してから、DockerComposeオーケストレーションサービスと連携する方が便利です。

3.1フラスコのウェブサイトのミラーを構築する

通常、ミラーにはFlask Webサイトの実行環境が含まれているため、Gunicornをイメージの実行コマンドとして使用できます。たとえば、OctBlogのDockerfileは次のように記述されます。

# MAINTAINER        Gevin <[email protected]>
# DOCKER-VERSION    18.03.0-ce, build 0520e24

FROM python:3.6.5-alpine3.7
LABEL maintainer="[email protected]"

RUN mkdir -p /usr/src/app  && \
    mkdir -p /var/log/gunicorn

WORKDIR /usr/src/app
COPY requirements.txt /usr/src/app/requirements.txt

RUN pip install --no-cache-dir gunicorn && \
    pip install --no-cache-dir -r /usr/src/app/requirements.txt

COPY . /usr/src/app


ENV PORT 8000
EXPOSE 8000 5000

CMD ["/usr/local/bin/gunicorn", "-w", "2", "-b", ":8000", "manage:app"]

ここで、Gevinは、最小のPython-alpineイメージを基本イメージとして直接使用します。これにより、構築されるFlaskアプリケーションイメージのボリュームが大幅に削減されます。わずか数メガバイトのアルパインなどの最小限のイメージの場合、他のシステム依存関係をインストールせずにpip install uwsgiエラーが直接報告されます。

3.2Nginx関連の構成

Nginxは、主にリバースプロキシと静的ファイルホスティングに使用されます。これは、次のような上記の構成ファイルと一致しています。

server {
    listen 80;

    server_name localhost;

    access_log  /var/log/nginx/access.log;
    error_log  /var/log/nginx/error.log;

    location / {
        proxy_pass         http://blog:8000/;
        proxy_redirect     off;

        proxy_set_header   Host             $http_host;
        proxy_set_header   X-Real-IP        $remote_addr;
        proxy_set_header   X-Forwarded-For  $proxy_add_x_forwarded_for;

    }

    location /media  {
        alias /usr/share/nginx/html/media;  
    }

    location /static  {
        alias /usr/share/nginx/html/static;  
    }
}

この構成ファイルと前の章の唯一の違いは、10行目のproxy_pass http://blog:8000/; リバースプロキシサービスblogがDocker-composeで構成されたOctBlogWebサイトサービスであることです。

3.3Docker-composeを使用してサービスをオーケストレーションします

OctBlogのDocker-composeオーケストレーションファイルは次のとおりです。

version: '3'
services:
  blog:
    # restart: always
    image: gevin/octblog:0.4.1
    volumes:
      - blog-static:/usr/src/app/static
    env_file: .env
    networks:
      - webnet

  mongo:
    # restart: always
    image: mongo:3.2
    volumes:
      - /Users/gevin/projects/data/mongodb:/data/db
    networks:
      - webnet

  blog-proxy:
    # restart: always
    image: nginx:stable-alpine
    ports:
      - "8080:80"
    volumes:
      - ./default.conf:/etc/nginx/conf.d/default.conf
      - blog-static:/usr/share/nginx/html/static:ro
      - blog-static:/usr/share/nginx/html/media:ro
    networks:
      - webnet


volumes:
  blog-static:
networks:
  webnet:

その中で、複数のサービスが相互に通信できるようにするために、カスタムネットワークが作成され webnet、ファイルを複数のサービス間で共有できるようにするために、ボリュームが共有され blog-staticます。

 

4.他のPythonWebサイトの展開

上記の内容に基づいて、類推により、Webサイト展開用のさまざまなPythonWebフレームワークの一般的なルーチンを分類することもできます。

  1. Python WSGI HTTPサーバーを使用して、次のようなコードをデプロイします。
  2. Nginxをリバースプロキシとして使用する
  3. 静的ファイルをうまくホストする

 

5.注:

  1. Nginxに加えて、サーバーソフトウェアにはApacheなどの他のオプションもあります。Gevinは他のサーバーソフトウェアの展開Python Webサイトを深く理解していないため、この記事では取り上げません。
  2. OctBlogのソースコードはGitHubでホストされておりflyhigher139 / OctBlogのリポジトリを検索表示できます

この記事を書くとき、私たちは次の内容を参照します、あなたはそれを拡張することができます:

なぜフラスコ+ nginx + gunicorn:

プレフォークについて:

Nginxはフラスコの静的ファイルを提供します:

おすすめ

転載: blog.csdn.net/smilejiasmile/article/details/110825837