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

基于Redis扩展Flask-Socket.IO遇请求集中单实例问题求助

问题分析

你的核心问题是所有客户端通过VPN使用同一个静态IP,导致Nginx的iphash负载均衡策略完全失效——所有请求都会被路由到同一个Flask-Socket.IO实例,最终引发单实例过载崩溃。要实现横向扩展,必须采用Flask-Socket.IO的集群方案,通过Redis作为消息中转站,让多个实例之间同步消息,同时调整负载均衡策略避免单实例压力集中。

基于Redis的Flask-Socket.IO集群解决方案

1. 调整Nginx负载均衡策略

由于客户端IP完全相同,iphash策略不再适用,将后端Nginx的上游配置改为最少连接(least_conn)或轮询(round_robin,默认),确保请求能均匀分配到所有实例:

upstream live_nodes {
    least_conn; # 优先分配请求到当前连接数最少的实例
    server 10.0.2.10:5000;
    server 10.0.2.11:5000;
    server 10.0.2.12:5000;
    # ... 添加剩余12个节点
}

2. 完善Nginx的Socket.IO代理配置

你的现有Nginx配置缺少WebSocket代理的关键参数,必须补充以下配置(前端和后端Nginx的location /块内都要添加):

# 支持WebSocket协议升级
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";

# 关闭缓冲,保证实时消息传输
proxy_buffering off;

修改后的前端Nginxlocation /块示例:

location / {
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
    proxy_set_header X-NginX-Proxy true;
    proxy_redirect off;
    proxy_read_timeout 360s; # 延长超时时间,适配长连接
    proxy_connect_timeout 120s;
    open_file_cache max=200000 inactive=20s;
    open_file_cache_valid 65s;
    open_file_cache_min_uses 2;
    open_file_cache_errors on;
    # 新增WebSocket支持配置
    proxy_http_version 1.1;
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_buffering off;
    client_max_body_size 0M;
    proxy_pass http://live_chatnodes;
}

后端Nginx的location /块做同样修改即可。

3. 配置Flask-Socket.IO的Redis消息队列

安装依赖

首先安装必要的Python包:

pip install flask-socketio redis eventlet # eventlet是推荐的异步服务器,也可以用gevent

修改Flask应用代码

在初始化SocketIO时指定Redis消息队列,让所有实例通过Redis同步消息:

from flask import Flask
from flask_socketio import SocketIO

app = Flask(__name__)
# 配置Redis连接,替换<redis-host>为你的Redis服务器地址(如10.0.2.15)
socketio = SocketIO(
    app,
    message_queue='redis://<redis-host>:6379/0', # 可添加密码:redis://:password@host:port/db
    cors_allowed_origins="*",
    async_mode='eventlet' # 指定异步模式,必须和安装的服务器匹配
)

# 示例聊天消息处理
@socketio.on('send_message')
def handle_send_message(data):
    # 广播消息到所有客户端,包括连接在其他实例上的客户端
    socketio.emit('receive_message', data, broadcast=True)

if __name__ == '__main__':
    socketio.run(app, host='0.0.0.0', port=5000, debug=False)

4. 验证集群功能

  1. 启动所有15个Flask-Socket.IO实例
  2. 启动修改后的前端和后端Nginx
  3. 用多个客户端连接测试:
    • 查看Nginx日志,确认请求被分配到不同的后端实例
    • 发送消息,验证所有客户端(即使连接到不同实例)都能收到消息
注意事项
  • 确保Redis服务器能被所有Flask-Socket.IO实例访问,建议配置Redis密码和防火墙规则保证安全
  • 若需要持久化消息,可开启Redis的RDB或AOF持久化
  • 生产环境建议关闭Flask的debug模式,使用eventlet或gevent作为异步服务器,避免性能问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 05:35:12