django - 在 systemd 上使用 daphne 运行 django channel

标签 django nginx systemd django-channels daphne

首先,很抱歉这个问题太长了,我希望你们中的一些人对此有耐心。

TL; DR:如何在 systemd 中正确加载 django 设置?

我正在关注本指南,Deploying Django Channels Using Daphne ,所以我可以运行一些实时应用程序(使用 WebSockets)。在没有 nginx 的情况下,从命令行运行 worker (python manage.py runworker) 和 interface (daphne),我可以访问正确的 channel 消费者类,如下面的日志所示(这些是从 javascript 客户端触发的) :

2017-10-09 21:10:35,210 - DEBUG - worker - Got message on websocket.connect (reply daphne.response.CYeWgnNQoY!mwuQrazQtv)
2017-10-09 21:10:35,211 - DEBUG - runworker - websocket.connect
2017-10-09 21:10:35,211 - DEBUG - worker - Dispatching message on websocket.connect to api.consumers.OrderConsumer
2017-10-09 21:10:48,132 - DEBUG - worker - Got message on websocket.receive (reply daphne.response.CYeWgnNQoY!mwuQrazQtv)
2017-10-09 21:10:48,132 - DEBUG - runworker - websocket.receive
2017-10-09 21:10:48,132 - DEBUG - worker - Dispatching message on websocket.receive to api.consumers.OrderConsumer

这些事件由以下 javascript 调用触发:
ws = new WebSocket("ws://localhost:8000/order/1/")
ws.send("test")

使用 nginx,并在 systemd 上同时运行接口(interface)和工作程序,尽管使用了完全相同的触发器输入,但我得到了以下日志。
2017-10-09 20:38:35,503 - DEBUG - worker - Got message on websocket.connect (reply daphne.response.PPGuXtBmQD!EgUfaNZjUj)
2017-10-09 20:38:35,503 - DEBUG - runworker - websocket.connect
2017-10-09 20:38:35,503 - DEBUG - worker - Dispatching message on websocket.connect to channels.routing.connect_consumer
2017-10-09 20:38:42,993 - DEBUG - worker - Got message on websocket.receive (reply daphne.response.PPGuXtBmQD!EgUfaNZjUj)
2017-10-09 20:38:42,993 - DEBUG - runworker - websocket.receive
2017-10-09 20:38:42,993 - DEBUG - worker - Dispatching message on websocket.receive to channels.routing.null_consumer

请注意接收 channel 被路由到 null_consumer .我相信这里的问题很简单,channels.routing设置不好。由于我在两个版本中使用相同的设置(Django 设置文件),这可能意味着设置本身没有被正确加载。请考虑以下文件。
## rest-api/farmaApp/settings.py

...
CHANNEL_LAYERS = {
    'default': {
        'BACKEND': 'asgi_redis.RedisChannelLayer',
        'CONFIG': {
            'hosts': [('localhost', 6379)],
        },
        'ROUTING': 'farmaApp.routing.channel_routing',
    }
}
...

应该设置channels.routing到:
## rest-api/farmaApp/routing.py

from channels.routing import route
from api.consumers import ws_connect, ws_disconnect, OrderConsumer

channel_routing = [
    route('websocket.connect', ws_connect, path=r'^/users/'),
    route('websocket.disconnect', ws_disconnect, path=r'^/users/'),
    OrderConsumer.as_route(path=r'^/order/(?P<order_id>[\d+])/'),
]

同样,我不认为配置本身是错误的,因为它可以在没有 systemd 的情况下工作。最后,这是我的 systemd 配置:
## /etc/systemd/system/daphne.service

[Unit]
Description=daphne daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/rest-api
Environment=DJANGO_SETTINGS_MODULE=farmaApp.settings
ExecStart=/home/ubuntu/rest-api/env/bin/daphne --access-log /home/ubuntu/rest-api/access.log -b 0.0.0.0 -p 8001 farmaApp.asgi:channel_layer

[Install]
WantedBy=multi-user.target


## /etc/systemd/system/django_worker.service
[Unit]
Description=django_worker daemon
After=network.target

[Service]
User=ubuntu
Group=www-data
WorkingDirectory=/home/ubuntu/rest-api
Environment=DJANGO_SETTINGS_MODULE=farmaApp.settings
ExecStart=/home/ubuntu/rest-api/env/bin/python manage.py runworker -v 2

[Install]
WantedBy=multi-user.target

请注意我根据链接指南导出到环境的 DJANGO_SETTINGS_MODULE 变量的两个配置文件。我相信这没有按预期工作。

最佳答案

我刚刚部署了我的 Django Channels 应用程序,并且以下 systemd 服务文件在不使用主管的情况下为我工作:
/etc/systemd/system/django-channels-daphne.service

[Unit]
Description=daphne server script for my project
After=network.target

[Service]
User=webuser
Group=webuser
WorkingDirectory=/path/to/myproject
Environment=DJANGO_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Environment=DJANGO_ALLOWED_HOSTS=myapp.chatbot.ai
ExecStart=/path/to/python/virtualenv/bin/daphne -b 0.0.0.0 -p 8000 myproject.asgi:channel_layer
Restart=always

[Install]
WantedBy=multi-user.target
/etc/systemd/system/django-channels-runworker.service
[Unit]
Description=python runworker server for myproject
After=network.target

[Service]
User=webuser
Group=webuser
WorkingDirectory=/path/to/myproject
Environment=DJANGO_SECRET_KEY=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Environment=DJANGO_ALLOWED_HOSTS=myapp.chatbot.ai
ExecStart=/path/to/python/virtualenv/bin/python /path/to/myproject/manage.py runworker --threads 4 
Restart=always

[Install]
WantedBy=multi-user.target
/path/to/myproject/myproject/asgi.py
import os
import channels

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "myproject.settings")
channel_layer = channels.asgi.get_channel_layer()
/path/to/myproject/myproject/settings.py 中的一些行:
ALLOWED_HOSTS = [os.environ['DJANGO_ALLOWED_HOSTS']]
SECRET_KEY = os.environ['DJANGO_SECRET_KEY']

关于django - 在 systemd 上使用 daphne 运行 django channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46655488/

相关文章:

logging - Journalctl : add _SYSTEMD_UNIT field into log printout

MySQL 不为外键创建索引

php - 如何使用 PHP-FPM 和 Nginx Docker 容器解决未知的 PHP-FPM 主脚本?

docker - 使用 nginx 的 docker certbot 容器检索证书时的用户权限问题

docker - 带有 envsubst 引号问题的 Nginx 配置

python - systemd中pyenv下的jupyter笔记本仅提供系统python

Django::OperationalError at/admin/login/无法打开数据库文件

python - 将文本和图像添加到图像的简单方法(对于 fb 应用程序) - PIL 在依赖性方面是 hell

python - 从代码自定义 CSS (Django)

linux - 什么是 systemd PID 文件?