Django+Python-Socketio在EC2上的可扩展WSGI部署方案咨询
Django + Python-Socketio 生产部署方案指南
a) 经过验证的可扩展部署栈
以下是实际生产环境中验证过的、适合Django+Python-Socketio的可扩展部署方案:
- Eventlet 独立服务器 + NGINX:这是python-socketio官方推荐的轻量栈。直接使用
eventlet.wsgi.server启动服务,扩展时可在同一EC2实例上启动多个Eventlet进程(每个绑定不同端口),通过NGINX的ip_hash配置实现粘性会话,将请求分发到多个进程。这种方案资源占用低,适合中小规模场景。 - Uvicorn ASGI服务器 + NGINX:Python-Socketio从v5.0开始支持ASGI标准,Uvicorn是原生ASGI服务器,对WebSocket和异步任务支持良好,且支持多worker进程。启动命令示例:
uvicorn myproject.asgi:application --workers 4 --host 0.0.0.0 --port 8000,NGINX代理时配置WebSocket升级和粘性会话即可,扩展性强,适合高并发场景。 - Gunicorn + Uvicorn Worker + NGINX:如果偏好Gunicorn的进程管理能力,可通过Gunicorn托管Uvicorn worker进程,兼顾进程管理和WebSocket兼容性。启动命令示例:
gunicorn myproject.asgi:application -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000,同样配合NGINX的粘性会话配置实现扩展。
b) Django + Gunicorn + NGINX 栈的兼容配置
若坚持使用该栈,需切换到ASGI模式并使用Uvicorn Worker解决兼容性和扩展性问题,具体步骤:
- 依赖安装:确保安装对应版本的依赖:
pip install gunicorn uvicorn python-socketio>=5.0 django
- 修改ASGI配置文件:在项目根目录的
asgi.py中集成Socket.io,示例代码:
import os import django from django.core.asgi import get_asgi_application import socketio os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'your_project.settings') django.setup() # 初始化Django ASGI应用 django_app = get_asgi_application() # 初始化异步Socket.io服务器 sio = socketio.AsyncServer(async_mode='asgi') # 注册Socket.io事件示例 @sio.event async def connect(sid, environ): print(f"Client {sid} connected") @sio.event async def disconnect(sid): print(f"Client {sid} disconnected") # 组合Socket.io和Django应用 application = socketio.ASGIApp(sio, django_app)
- 启动Gunicorn服务:使用Uvicorn Worker启动,指定worker数量(根据EC2实例CPU核心数调整,一般为核心数*2):
gunicorn your_project.asgi:application -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
- NGINX代理配置:在server块中添加WebSocket支持和粘性会话配置,确保WebSocket连接保持在同一worker进程:
location /socket.io/ { proxy_pass http://127.0.0.1:8000; 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_set_header X-Forwarded-Proto $scheme; # 粘性会话配置 ip_hash; } location / { proxy_pass http://127.0.0.1:8000; 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; }
- 关键注意事项:
- 避免使用eventlet/gevent作为Gunicorn Worker,二者存在兼容性问题且仅支持单worker;
- 必须使用ASGI模式而非WSGI模式,WSGI对WebSocket的支持有限,无法实现真正的多worker扩展;
- 启用
ip_hash确保同一客户端的WebSocket连接始终路由到同一worker,避免连接中断。
内容的提问来源于stack exchange,提问作者cambrialas
相关产品推荐
相关产品推荐

