这是一个老问题,但我想我无论如何都会回答它,因为我最近遇到了同样的问题,并且认为我可以对此有所了解。
Django 通道如何工作
Django Channels 是 Django 之上的另一层,它有两种流程类型:
- 接受 HTTP/Websocket 的一种
- 运行 Django 视图、Websocket 处理程序、后台任务等的一个
基本上,当请求传入时,它首先到达接口服务器 (Daphne),该服务器接受 HTTP/Websocket 连接并将其放入 Redis 队列中。然后,工作人员(消费者)会看到它,将其从队列中取出并运行视图逻辑(例如 Django 视图、WS 处理程序等)。
为什么它对你不起作用
因为您只运行工作线程(消费者),并且它阻止了接口服务器(生产者)的执行。这意味着,不会接受任何连接,并且工作人员只是盯着空的 Redis 队列。
我是如何让它发挥作用的
我将 Daphne、redis 和工人作为单独的容器运行,以便于扩展。数据库迁移、静态文件收集等仅在 Daphne 容器中执行。该容器将仅运行一个实例,以确保没有并行数据库迁移正在运行。
另一方面,工作人员可以扩大或缩小规模来处理传入的流量。
如何让它发挥作用
将您的设置分为at least两个容器。我不建议在一个容器中运行所有内容(使用导师 http://supervisord.org例如)。为什么?因为当需要扩展设置时,没有简单的方法可以做到。您可以将容器扩展到两个实例,但这只会创建另一个包含 daphne、redis、django 的主管...如果您将工作程序与 daphne 分开,您可以轻松地扩展工作程序容器以处理不断增长的传入请求。
一个容器可以运行:
#!/usr/bin/env bash
python wait_for_postgres.py
python manage.py migrate
python manage.py collectstatic --no-input
daphne team_up.asgi:channel_layer --port 8000 -b 0.0.0.0
而另一个:
#!/usr/bin/env bash
python wait_for_postgres.py
python manage.py runworker --only-channels=http.* --only-channels=websocket.* -v2
“makemigrations”命令
无需运行您提供的脚本中的命令,如果有任何事情可能会因为等待输入的某些问题而阻止整个事情(例如“您是否将 X 列重命名为 Y ?”)。
相反,您可以在正在运行的容器中执行它,如下所示:
docker exec -it <container_name> python manage.py makemigrations