Gunicorn部署Django Channels时WebSocket连接异常求助
问题描述
我用Django Channels和Daphne实现了在线聊天功能,本地运行正常,但生产环境采用Gunicorn+Nginx部署后,重启服务出现连接错误(见附图)。修改服务配置未解决问题,因无具体报错信息无法定位原因,请问需要执行makemigrations吗?求排查思路。
以下是已尝试的配置:
Gunicorn服务配置
[Unit] Description=Tris application daemon services Requires=tev.socket After=network.target [Service] User=dswdcaraga Group=www-data WorkingDirectory=/opt/apps/tev Environment=DJANGO_SETTINGS_MODULE=tev.settings ExecStart=/opt/apps/env/bin/daphne -u /run/tev/tev.sock tev.asgi:application --bind 0.0.0.0:8000 [Install] WantedBy=multi-user.target
Nginx配置
server { server_name caraga-tris-staging.dswd.gov.ph; listen 80; return 301 https://caraga-tris-staging.dswd.gov.ph$request_uri; } server { server_name caraga-tris-staging.dswd.gov.ph; listen 443 ssl; #ssl_certificate /etc/ssl/certs/caraga/server-cer.pem; #ssl_certificate_key /etc/ssl/certs/caraga/server-key.key; ssl_certificate /etc/ssl/certs/caraga/ssl_nginx/server-cer.pem; ssl_certificate_key /etc/ssl/certs/caraga/ssl_nginx/server-key.key; location / { include proxy_params; proxy_pass http://unix:/run/tev/tev.sock; #WebSocket support proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "Upgrade"; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } proxy_headers_hash_max_size 1024; proxy_headers_hash_bucket_size 128;
asgi.py配置
import os from django.core.asgi import get_asgi_application from channels.routing import ProtocolTypeRouter, URLRouter #from django.core.asgi import get_asgi_application from channels.auth import AuthMiddlewareStack from main import routing import main.routing os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tev.settings') django.setup() django_asgi_app = get_asgi_application() #application = get_asgi_application() application = ProtocolTypeRouter({ #"http": get_asgi_application(), "http": django_asgi_app, "websocket": URLRouter( main.routing.websocket_urlpatterns ) })
解答
关于makemigrations
不需要执行makemigrations,你的问题属于WebSocket连接异常,和数据库模型变更无关。本地能正常运行说明迁移已完成,生产环境重启服务无需重复迁移操作。
排查步骤
检查Daphne服务状态
- 执行
sudo systemctl status tev.service确认服务是否正常启动 - 查看实时日志:
sudo journalctl -u tev.service -f,重启服务后捕捉报错信息
- 执行
修复Unix Socket权限问题
- 执行
ls -l /run/tev/tev.sock检查Socket文件的所属用户/组是否为dswdcaraga:www-data - 若权限错误,执行
sudo chown -R dswdcaraga:www-data /run/tev/修正;或在systemd配置的[Service]块中添加RuntimeDirectory=tev,让系统自动创建目录并设置正确权限
- 执行
修正Daphne启动命令
- 启动命令同时指定Unix Socket(
-u)和TCP端口(--bind)会导致冲突,二选一即可。推荐保留Unix Socket,修改ExecStart为:ExecStart=/opt/apps/env/bin/daphne -u /run/tev/tev.sock tev.asgi:application
- 启动命令同时指定Unix Socket(
完善Nginx配置
- 将
proxy_headers_hash_max_size和proxy_headers_hash_bucket_size移至location /块内或http块 - 添加WebSocket超时配置,避免连接被过早断开:
proxy_connect_timeout 7d; proxy_send_timeout 7d; proxy_read_timeout 7d; - 检查
proxy_params文件,确保未覆盖WebSocket相关请求头
- 将
优化ASGI配置
- 删除多余的
django.setup(),get_asgi_application()已自动完成Django初始化 - 若聊天功能需要用户认证,WebSocket路由需添加
AuthMiddlewareStack:"websocket": AuthMiddlewareStack( URLRouter( main.routing.websocket_urlpatterns ) )
- 删除多余的
直接测试WebSocket连接
- 用
wscat工具测试:先临时用TCP端口启动Daphne,执行wscat -c ws://localhost:8000/你的WebSocket路径 - 或通过Nginx测试:
wscat -c wss://caraga-tris-staging.dswd.gov.ph/你的WebSocket路径,验证连接是否正常
- 用
内容的提问来源于stack exchange,提问作者Henry
相关产品推荐
相关产品推荐

