如何在多处理器上分配Daphne请求?Docker部署Django ASGI应用提速
解决Daphne单CPU负载过高及Uvicorn多Worker布局丢失的实用方案
一、搞定Daphne单进程负载集中的问题
Daphne默认单进程运行,所有请求都会集中在单个CPU核心上,最简单的提速方式就是启动多个Daphne实例,让Nginx把请求分发到这些实例,充分利用多核CPU性能。
Docker环境下的具体操作
启动多个Daphne进程(数量建议和服务器核心数匹配,比如4核服务器开3个进程,留1核给系统):
将Docker启动命令修改为:daphne WBT.asgi:application --bind 0.0.0.0 --port 8000 & daphne WBT.asgi:application --bind 0.0.0.0 --port 8001 & daphne WBT.asgi:application --bind 0.0.0.0 --port 8002 & wait用
&让每个进程后台运行,wait保证容器不会因进程启动后直接退出。配置Nginx做负载均衡:
修改Nginx反向代理配置,指向多个Daphne端口,采用最少连接策略让负载更均匀:upstream daphne_backend { server 127.0.0.1:8000; server 127.0.0.1:8001; server 127.0.0.1:8002; least_conn; } server { listen 80; server_name your-domain.com; location / { proxy_pass http://daphne_backend; 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-Proto $scheme; # 如果使用Channels实现WebSocket,添加以下配置 proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
二、修复Uvicorn多Worker的布局丢失问题
你遇到的25%概率布局丢失,基本是静态文件加载不一致或Worker间状态不共享导致的,按以下步骤快速修复:
- 静态文件全交给Nginx托管:禁止Uvicorn处理静态文件,由Nginx直接返回,避免Worker间的加载差异。添加一段Nginx配置:
location /static/ { alias /path/to/your/static/root/; expires 30d; } - 关闭Uvicorn的静态文件服务:启动Uvicorn时添加
--static-dir ""参数,强制静态文件走Nginx,命令示例:uvicorn WBT.asgi:application --host 0.0.0.0 --port 8000 --workers 4 --static-dir "" - 改用共享缓存/会话存储:如果Django使用
LocMemCache或内存会话,替换为Redis或Memcached,确保所有Worker能访问相同的会话数据,避免布局依赖的状态在不同Worker上不一致。 - 确保静态文件收集完整:部署前必须执行
python manage.py collectstatic,将所有App的静态文件集中到同一目录,避免不同Worker加载不同位置的文件。
三、更省心的替代方案
如果觉得手动启动多个Daphne太繁琐,直接用Gunicorn搭配Uvicorn Worker,Gunicorn会自动管理多Worker进程,无需手动配置端口:
gunicorn WBT.asgi:application --workers 4 --worker-class uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
配合上述静态文件托管和共享缓存配置,既能利用多核CPU,又能解决布局丢失问题,一步到位。
内容的提问来源于stack exchange,提问作者MijatTomić
相关产品推荐
相关产品推荐

