Daphne监听8001端口报地址占用但WebSocket正常运行问题
问题现象
生产环境使用django-channels搭配Daphne部署服务时,查看systemd托管的daphne.service状态提示监听失败,报错信息如下:
daphne service listen failure: Couldn't listen on 0.0.0.0:8001 Address already in use
即无法监听0.0.0.0:8001,地址已被占用。
反常表现:前端WebSocket连接完全正常,可与服务端正常双向收发消息,所有业务功能运行无异常,仅systemd的daphne服务状态持续报上述端口占用错误。
8001端口占用情况参考截图:
现有相关配置
1. systemd服务配置
文件路径:/etc/systemd/system/daphne_seb.service
# /etc/systemd/system/daphne_seb.service [Unit] Description=daphne daemon After=network.target [Service] User=simple Group=www-data WorkingDirectory=/home/simple/my_proj ExecStart=/home/simple/my_proj/venv/bin/daphne -b 0.0.0.0 -p 8001 project.asgi:application Restart=on-failure [Install] WantedBy=multi-user.target
2. Supervisor托管的Daphne ASGI配置
文件路径:/etc/supervisor/conf.d/daphne_proj.conf
# /etc/supervisor/conf.d/daphne_proj.conf [fcgi-program:asgi] # Nginx后端上游服务使用的TCP套接字 socket=tcp://localhost:8001 # 项目文件所在目录 directory=/home/simple/my_proj # 启动命令,每个进程使用独立sock文件,通过传递的文件句柄接收请求 command=/home/simple/my_proj/venv/bin/daphne -u /run/daphne/daphne%(process_num)d.sock --endpoint fd:fileno=0 --access-log - --proxy-headers project.asgi:application # 启动进程数,通常配置为CPU核心数 numprocs=4 # 进程唯一命名标识 process_name=asgi%(process_num)d # 自动启动、异常自动重启 autostart=true autorestart=true # 日志路径配置 stdout_logfile=/home/simple/my_bg/daphne.log redirect_stderr=true
3. Nginx反向代理配置
upstream websocket { server 0.0.0.0:8001; } server { listen 80; server_name MY_SERVER_DOMAIN; location = /favicon.ico { access_log off; log_not_found off; } location / { include proxy_params; proxy_pass http://unix:/home/simple/my_proj/myproject.sock; } location /ws/ { proxy_pass http://websocket; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; 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_set_header X-Forwarded-Host $server_name; } }
问题原因
- 核心问题是Daphne服务被systemd、Supervisor两个进程管理器重复托管,且两份配置都声明占用8001端口。
- 实际承载业务的是Supervisor托管的Daphne进程组:Supervisor的fcgi-program模式会预先绑定
tcp://localhost:8001端口,再将端口句柄传递给后端启动的4个Daphne工作进程处理请求,因此WebSocket连接、消息收发完全正常。 - Supervisor完成端口绑定后,systemd托管的daphne服务启动时尝试绑定
0.0.0.0:8001,必然触发地址占用报错;加上该服务配置了Restart=on-failure策略,会持续处于失败-重启的循环状态,但该服务本身没有承载任何流量,因此不会影响现有业务运行。
解决方案
两个方案二选一即可,禁止同时使用两个进程管理器托管同端口的Daphne服务:
- 方案1:保留Supervisor托管(推荐,现有配置已支持多进程,并发性能更好)
- 停掉并禁用systemd侧的冗余daphne服务,执行以下命令:
sudo systemctl stop daphne_seb.service sudo systemctl disable daphne_seb.service - 修正Nginx配置不规范项:将websocket upstream中的
0.0.0.0:8001改为127.0.0.1:8001,同时将proxy_set_header Connection后的中文引号替换为英文引号,校验配置后重载Nginx:sudo nginx -t && sudo systemctl reload nginx
- 停掉并禁用systemd侧的冗余daphne服务,执行以下命令:
- 方案2:保留systemd托管
- 停掉并移除Supervisor侧的asgi服务,执行以下命令:
sudo supervisorctl stop asgi:* # 可直接删除daphne_proj.conf配置文件,或注释掉文件内所有配置 sudo rm /etc/supervisor/conf.d/daphne_proj.conf sudo supervisorctl reread && sudo supervisorctl update - 注意:当前systemd配置的Daphne为单进程模式,生产环境使用需要额外配置多进程启动方案,否则高并发场景下性能不足。
- 停掉并移除Supervisor侧的asgi服务,执行以下命令:
内容的提问来源于stack exchange,提问作者coder
相关产品推荐
相关产品推荐

