Django Channels运行一段时间后停止工作的问题求助
问题背景
系统支持HTTP(处理常规任务)和WebSocket(实时通信)两种通信方式,部署架构为Nginx + Daphne + Redis,相关配置及依赖版本如下:
Service配置
[Unit] Description=FBO Requires=fbo.socket After=network.target [Service] User=www-data Group=www-data WorkingDirectory=/var/www/api.fbo.org.py/backend Environment="DJANGO_SETTINGS_MODULE=fbo-backend.settings" ExecStart=/var/www/api.fbo.org.py/backend/.venv/bin/daphne \ --bind 127.0.0.1 -p 8001 \ fbo-backend.asgi:application [Install] WantedBy=multi-user.target
Nginx配置
server { server_name api.fbo.org.py; access_log /var/log/nginx/access.log custom_format; location /static/ { alias /var/www/api.fbo.org.py/backend/staticfiles/; expires 86400; log_not_found off; } location /media/ { root /var/www/api.fbo.org.py/backend; expires 86400; log_not_found off; } location / { proxy_pass http://localhost:8001; proxy_set_header Host $host; proxy_set_header X-Real_IP $remote_addr; } location /ws/ { proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_redirect off; proxy_pass http://127.0.0.1:8001; 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; } }
依赖版本
channels==4.0.0 channels-redis==4.2.0 daphne==4.1.2 Django==3.2.25
错误日志
系统崩溃时重复出现以下警告:
WARNING Application instance <Task pending name='Task-3802' coro=<ProtocolTypeRouter.__call__() running at /var/www/api.bancodeojos.org.py/backend/.venv/lib/python3.8/site-packages/channels/routing.py:62> wait_for=<Future pending cb=[shield.<locals>._outer_done_callback() at /usr/lib/python3.8/asyncio/tasks.py:902, <TaskWakeupMethWrapper object at 0x7f93a6c84c70>()]>> for connection <WebRequest at 0x7f93a6754b80 method=PUT uri=/turns/9141/ clientproto=HTTP/1.0> took too long to shut down and was killed.
已尝试更换依赖版本、延长响应时间,均未解决问题,求可行的解决思路。
解决思路
1. 排查HTTP请求的阻塞点
日志触发的是PUT /turns/9141/请求,优先排查该接口:
- 检查接口内是否存在同步阻塞操作(如长时间数据库查询、第三方API调用、大文件IO),Daphne是异步服务器,同步代码会阻塞事件循环,导致请求无法及时关闭。
- 将同步操作改为异步实现,比如使用Django的
async def视图,或用sync_to_async包装时设置合理超时时间。
2. 调整Daphne的关闭超时参数
Daphne默认应用实例关闭超时为60秒,可通过启动参数延长:
修改systemd服务的ExecStart行,添加--shutdown-timeout参数(示例设为120秒):
ExecStart=/var/www/api.fbo.org.py/backend/.venv/bin/daphne \ --bind 127.0.0.1 -p 8001 \ --shutdown-timeout 120 \ fbo-backend.asgi:application
修改后重启服务:
sudo systemctl daemon-reload && sudo systemctl restart fbo.service
3. 补充Nginx代理超时配置
当前Nginx未设置代理超时,可能导致Nginx提前断开连接,Daphne仍在处理请求最终触发超时:
在location /块添加:
proxy_connect_timeout 60s; proxy_send_timeout 120s; proxy_read_timeout 120s;
WebSocket的location /ws/块补充:
proxy_connect_timeout 60s; proxy_send_timeout 300s; proxy_read_timeout 300s;
修改后重启Nginx:
sudo systemctl restart nginx
4. 检查Channels路由与ASGI配置
- 确认
ProtocolTypeRouter配置正确,HTTP与WebSocket路由是否隔离,避免HTTP请求误入WebSocket处理逻辑。 - 检查ASGI应用中是否有未捕获的异常,异常可能导致任务挂起无法正常关闭。
5. 排查Redis与Channels通道层问题
- 检查Redis服务稳定性,是否存在连接超时、队列堆积情况,Channels依赖Redis做通道层,Redis异常会引发任务阻塞。
- 查看Channels通道层日志,排查
channels-redis的连接或操作错误。
6. 监控异步任务状态
使用asyncio调试工具或Django监控插件,跟踪Daphne事件循环状态,定位长时间运行的任务,找到具体阻塞点。
内容的提问来源于stack exchange,提问作者fscoscia
相关产品推荐
相关产品推荐

