21

我有一个 django 项目,最近添加了使用 websockets 的频道。这似乎一切正常,但我遇到的问题是准备好生产。

我的设置如下:

Nginx web server
Gunicorn for django
SSL enabled

因为我已经在混音中添加了频道。我花了最后一天试图让它工作。

在所有的教程中,他们都说你在某个端口上运行 daphne,然后展示如何为此设置 nginx。

但是让 gunicorn 为 django 服务呢?

所以现在我有 guncorn 在 8001 上运行这个 django 应用程序

如果我在另一个端口上运行 daphne,比如说 8002 - 它应该如何知道这个 django 项目的标准?那么运行工人呢?

Gunicorn、Daphne 和 runworkers 应该一起跑步吗?

4

3 回答 3

24

这个问题实际上在最新的Django Channels 文档中得到了解决:

使用像 /ws/ 这样的公共路径前缀来区分 WebSocket 连接和普通 HTTP 连接是一种很好的做法,因为它会使在某些配置中将 Channels 部署到生产环境中变得更加容易。

特别是对于大型站点,可以配置像 nginx 这样的生产级 HTTP 服务器,以根据路径将请求路由到(1)用于普通 HTTP 请求的生产级 WSGI 服务器(如 Gunicorn+Django)或(2)生产- 级 ASGI 服务器,例如用于 WebSocket 请求的 Daphne+Channels。

请注意,对于较小的站点,您可以使用更简单的部署策略,其中 Daphne 服务所有请求 - HTTP 和 WebSocket - 而不是拥有单独的 WSGI 服务器。在此部署配置中,不需要像 /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 套接字文件。)

于 2018-07-27T22:02:59.603 回答
7

我创建了一个如何混合 Django Channels 和 Django Rest Framework的示例。我将 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;
    }

}
于 2018-10-25T09:41:29.253 回答
2

我最近回答了一个类似的问题,看看那里有关 django 频道如何工作的解释。

基本上,你不再需要 gunicorn 了。您有 daphne,它是接受 HTTP/Websockets 的接口服务器,并且您有运行 django 视图的工作人员。然后显然你有你的频道后端将所有东西粘合在一起。

要使其工作,您必须CHANNEL_LAYERS在 settings.py 中进行配置并运行接口服务器:

$ daphne my_project.asgi:channel_layer

和你的工人:

$ python manage.py runworker

注意!如果您选择 redis 作为通道后端,请注意您提供的文件大小。如果您有大型静态文件,请确保 NGINX 为它们提供服务,否则客户端将遇到由于 redis 内存不足而可能发生的神秘错误。

于 2018-01-06T22:33:24.997 回答