Python Asyncio/Aiohttp Websocket客户端处理Bitfinex多交易对异常问题
可能的原因及解决方案
这问题我之前帮朋友排查过类似的,Bitfinex的Websocket服务在并发订阅大量交易对时确实容易踩这类坑,结合你描述的“少于30个正常,超过就进不了save_data协程”的场景,大概率是下面几个原因导致的:
1. Bitfinex单个Websocket连接的订阅数量限制
Bitfinex对单个WS连接的订阅频道数有隐性限制(大概率就是30左右),当你超过这个数量后,服务器可能会静默拒绝后续的订阅请求,或者你的客户端因为同时接收的消息量过载,导致部分消息丢失——没有数据需要保存,自然就触发不了save_data协程。
解决方案:
- 拆分多个WS连接,比如每25个交易对用一个独立的连接,分散订阅压力;
- 核对Bitfinex官方文档的订阅限制说明,确保每个连接的订阅数在允许范围内。
2. Asyncio事件循环的任务调度被“抢占”
当订阅大量交易对后,WS客户端会收到巨量的实时行情数据,如果你在消息回调里直接做数据解析等同步/耗时操作,这些任务会占满asyncio事件循环的调度时间,导致save_data这类低优先级的协程根本得不到执行机会(也就是被“饿死”了)。
解决方案:
- 用
asyncio.Queue做数据缓冲:把解析后的行情数据先放进队列,让save_data协程单独从队列里取数据保存; - 避免在消息回调里做同步IO操作(比如直接写本地文件、调用同步数据库接口),一定要用异步IO的库(比如asyncpg、aiofiles)来处理保存逻辑。
3. Websocket客户端的消息处理瓶颈
如果你用的是第三方WS客户端库(比如aiohttp的websocket模块),在高并发消息场景下,如果消息解析逻辑太复杂、耗时太长,会导致客户端的接收缓冲区溢出,后续消息被丢弃,甚至客户端直接卡住,根本没机会触发save_data的调用。
解决方案:
- 优化消息解析代码,去掉不必要的计算逻辑;
- 如果用的是Bitfinex的SDK,查看是否有批量处理消息、调整接收缓冲区大小的配置参数,尽量减少单条消息的处理耗时。
4. 操作系统的文件描述符限制
每个WS连接都会占用一个系统文件描述符,当你订阅大量交易对(如果每个交易对用单独连接的话),很容易超过操作系统默认的文件描述符上限(默认一般是1024,但有些环境可能更低),导致新连接失败或现有连接异常,数据断流后save_data自然没有数据可处理。
解决方案:
- 临时调整文件描述符限制:Linux/macOS下可以用
ulimit -n 2048命令临时提升上限; - 永久修改系统配置:比如在Linux下修改
/etc/security/limits.conf文件,设置soft nofile和hard nofile的数值; - 尽量复用WS连接,不要给每个交易对单独开连接。
内容的提问来源于stack exchange,提问作者pipinstallme
相关产品推荐
相关产品推荐

