You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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连接异常,和数据库模型变更无关。本地能正常运行说明迁移已完成,生产环境重启服务无需重复迁移操作。

排查步骤

  1. 检查Daphne服务状态

    • 执行sudo systemctl status tev.service确认服务是否正常启动
    • 查看实时日志:sudo journalctl -u tev.service -f,重启服务后捕捉报错信息
  2. 修复Unix Socket权限问题

    • 执行ls -l /run/tev/tev.sock检查Socket文件的所属用户/组是否为dswdcaraga:www-data
    • 若权限错误,执行sudo chown -R dswdcaraga:www-data /run/tev/修正;或在systemd配置的[Service]块中添加RuntimeDirectory=tev,让系统自动创建目录并设置正确权限
  3. 修正Daphne启动命令

    • 启动命令同时指定Unix Socket(-u)和TCP端口(--bind)会导致冲突,二选一即可。推荐保留Unix Socket,修改ExecStart为:
      ExecStart=/opt/apps/env/bin/daphne -u /run/tev/tev.sock tev.asgi:application
      
  4. 完善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相关请求头
  5. 优化ASGI配置

    • 删除多余的django.setup(),get_asgi_application()已自动完成Django初始化
    • 若聊天功能需要用户认证,WebSocket路由需添加AuthMiddlewareStack:
      "websocket": AuthMiddlewareStack(
          URLRouter(
              main.routing.websocket_urlpatterns
          )
      )
      
  6. 直接测试WebSocket连接

    • 用wscat工具测试:先临时用TCP端口启动Daphne,执行wscat -c ws://localhost:8000/你的WebSocket路径
    • 或通过Nginx测试:wscat -c wss://caraga-tris-staging.dswd.gov.ph/你的WebSocket路径,验证连接是否正常

内容的提问来源于stack exchange,提问作者Henry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 01:53:18