web-dev-qa-db-ja.com

Django ChannelsNginxプロダクション

Djangoプロジェクトがあり、最近WebSocketを使用するためのチャネルが追加されました。これはすべて正常に機能しているようですが、問題は本番環境の準備です。

私の設定は次のとおりです。

Nginx web server
Gunicorn for Django
SSL enabled

ミックスにチャンネルを追加したので。私はそれを機能させるために最後の日を過ごしました。

すべてのturtotialsで、あるポートでdaphneを実行し、そのためにnginxをセットアップする方法を示していると言われています。

しかし、gunicornがdjangoを提供するのはどうですか?

これで、8001でこのDjangoアプリを実行しているガンコーンがあります

別のポートでdaphneを実行する場合、8002としましょう-このDjangoプロジェクトのパーをどのように知る必要がありますか?実行ワーカーはどうですか?

Gunicorn、Daphne、およびrunworkersはすべて一緒に実行する必要がありますか?

8
Harry

この質問は実際には最新の Django Channels docs で対処されています:

/ ws /のような共通のパスプレフィックスを使用して、WebSocket接続を通常のHTTP接続と区別することをお勧めします。これにより、特定の構成での実稼働環境へのチャネルのデプロイが容易になります。

特に大規模なサイトの場合、(1)通常のHTTPリクエスト用のGunicorn + DjangoなどのプロダクショングレードのWSGIサーバー、または(2)プロダクションのいずれかにパスに基づいてリクエストをルーティングするように、nginxなどのプロダクショングレードのHTTPサーバーを構成できます。 -WebSocketリクエスト用のDaphne + ChannelsのようなグレードのASGIサーバー。

小規模なサイトの場合、個別のWSGIサーバーを使用するのではなく、Daphneがすべてのリクエスト(HTTPとWebSocket)を処理する単純なデプロイメント戦略を使用できることに注意してください。このデプロイメント構成では、/ ws /のような共通パスプレフィックスは必要ありません。

実際には、NGINX構成は次のようになります(関連するビットのみを含むように短縮されます)。

upstream daphne_server {
  server unix:/var/www/html/env/run/daphne.sock fail_timeout=0;
}

upstream gunicorn_server {
  server unix:/var/www/html/env/run/gunicorn.sock fail_timeout=0;
}

server { 
  listen   80; 
  server_name _;

  location /ws/ {
    proxy_pass http://daphne_server;
  }

  location / {
    proxy_pass http://gunicorn_server;
  }
}

(上記では、GunicornサーバーとDaphneサーバーをUnixソケットファイルにバインドしていることを前提としています。)

9
Kal

混合方法DjangoチャネルとDjangoRestFramework。nginxルーティングを次のように設定しました。

  • websockets接続はdaphneサーバーに接続されます
  • HTTP接続(REST API)はgunicornサーバーに接続されます

これが私のnginx設定ファイルです:

upstream app {
    server wsgiserver:8000;
}

upstream ws_server {
    server asgiserver:9000;
}


server {
    listen 8000 default_server;
    listen [::]:8000;

    client_max_body_size 20M;

    location / {
        try_files $uri @proxy_to_app;
    }

    location /tasks {
        try_files $uri @proxy_to_ws;
    }

    location @proxy_to_ws {
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
        proxy_redirect off;

        proxy_pass   http://ws_server;
    }

    location @proxy_to_app {
        proxy_set_header X-Forwarded-Proto https;
        proxy_set_header X-Url-Scheme $scheme;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_Host;
        proxy_redirect off;

        proxy_pass   http://app;
    }

}
2
pplonski

私は最近、同様の 質問 に回答しました。そこで、Djangoチャネルがどのように機能するかについての説明をご覧ください。

基本的に、gunicornはもう必要ありません。 HTTP/Websocketを受け入れるインターフェースサーバーであるdaphneがあり、Djangoビューを実行するワーカーがあります。そして、明らかに、すべてを結合するチャネルバックエンドがあります。

これを機能させるには、settings.pyでCHANNEL_LAYERSを構成し、インターフェイスサーバーを実行する必要があります。

$ daphne my_project.asgi:channel_layer

とあなたの労働者:

$ python manage.py runworker

NB!チャネルバックエンドとしてredisを選択した場合は、提供しているファイルサイズに注意してください。大きな静的ファイルがある場合は、NGINXがそれらを提供していることを確認してください。そうしないと、redisのメモリ不足が原因でクライアントに不可解なエラーが発生する可能性があります。

1
r00m