单机支撑5000+ websocket连接需避免内存泄漏与性能瓶颈:必须用set替代list存储连接并配合try/except及时discard异常连接;广播改用asyncio.gather+semaphore限流并发;严禁同步阻塞操作,全栈异步化;合理配置uvicorn worker数、限流及压缩参数。

单机撑住 5000+ 活跃 WebSocket 连接不难,但卡在 active_connections.append(websocket)、for conn in connections: await conn.send_text() 或混入 time.sleep() 这几处,就必然内存暴涨、广播延迟飙升、连接假死。
为什么用 list 存连接会内存泄漏
常见写法是定义全局 active_connections = [],每次 await websocket.accept() 后 append(websocket);问题在于:客户端异常断开(关浏览器、断网)时,websocket.send_text() 会抛出 WebSocketDisconnect 或 OSError,而代码若没捕获,该连接对象就永远留在列表里 —— 对象引用不释放,Python GC 不回收,内存持续上涨。
- 必须改用
set:它天然去重,且删除操作平均 O(1) - 每次广播前必须
try/except包裹send_text(),捕获WebSocketDisconnect和通用Exception,并在 except 块中执行connections.discard(websocket) - 不要依赖
finally清理 —— 异常可能发生在 send 之前(比如网络缓冲区满),finally未必执行
广播消息不能 for-loop + await 串行发
当连接数超 200,for conn in connections: await conn.send_text(...) 是严重瓶颈。每个 await 都要等前一个完成,2000 个连接 × 平均 5ms 发送耗时 = 10 秒纯等待,用户感知就是“消息发出去没反应”。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
- 改用
asyncio.gather(*[conn.send_text(...) for conn in connections], return_exceptions=True) -
return_exceptions=True很关键:避免单个连接失败导致整个广播中断 - 但注意别无限制并发 —— 10000 个并发
send_text()可能压垮 socket 缓冲区,建议加限流:asyncio.Semaphore(50)控制同时发送数
async def websocket_endpoint() 里绝对不能出现同步阻塞
所有耗时操作都必须异步化,否则卡死整个事件循环,所有连接一起变卡。这不是“慢”,而是“全停”。
- 禁止
time.sleep()、requests.get()、json.loads(big_json_str)、未加await的数据库查询(如session.query(...).all()) - HTTP 调用换
httpx.AsyncClient,数据库换asyncpg或aiomysql - CPU 密集型操作(如大 JSON 解析、base64 解码)丢进线程池:
await asyncio.to_thread(json.loads, data) - Pydantic 模型校验默认同步,高频场景下考虑用
model_validate_json()避免重复解析,或关掉验证:model_config = ConfigDict(validate_assignment=False)
Uvicorn worker 数和连接数配置不是越多越好
很多人以为 -w 16 就比 -w 4 更强,实际是反效果:Uvicorn 每个 worker 独占一个事件循环,worker 太多会导致 CPU 上下文切换激增、内存冗余、文件描述符快速耗尽。
- 推荐值:
-w $(( $(nproc) * 1 ))或-w $(( $(nproc) * 1.5 ))(例如 4 核机器设-w 4或-w 6) - 必须加
--limit-concurrency 100,防止单个 worker 接收过多连接压垮内存 - 务必启用
--ws-per-message-deflate,文本消息压缩率通常 >40%,显著降低带宽和延迟 - 生产环境禁用
--reload—— 它 fork 多进程,各 worker 内存状态不同步,set管理的连接无法跨进程共享
真正难的不是写通 WebSocket,而是让成百上千个连接长期稳定共存:连接清理靠 set + try/except,广播靠 gather + semaphore,IO 靠全异步栈,资源靠精准的 uvicorn 参数 —— 少踩一处,性能就差一个数量级。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










