Python实现300个币安websocket连接并行拉取行情的问题求助
实现方案
技术选型
优先选择asyncio实现:你的场景属于典型的IO密集型任务,300个WebSocket连接绝大多数时间处于等待数据推送的状态,协程切换的开销远低于多线程/多进程,单线程即可轻松承载上千个WebSocket连接,端到端延迟可以稳定控制在20ms以内,完全满足100ms的性能要求。
依赖安装
使用异步WebSocket库websockets实现连接,无需额外依赖:
pip install websockets
核心实现逻辑
- 所有协程运行在单线程内,共享的结果存储列表不需要加锁,直接操作不会出现并发冲突
- 单个交易对对应独立的协程任务,各自维护连接、接收数据、执行计算、写入结果列表
- 批量启动所有协程,统一管理断连重连逻辑
可运行示例代码
import asyncio import websockets import json # 统一存储所有交易对的处理结果 result_list = [] # 你的300个交易对对应的WebSocket URL列表,这里替换成你自己的实际url WS_URLS = [ "wss://stream.binance.com:9443/ws/btcusdt@trade", "wss://stream.binance.com:9443/ws/ethusdt@trade", # 剩下298个url自己补充 ] async def handle_single_symbol(ws_url: str): # 断连自动重连逻辑 while True: try: async with websockets.connect(ws_url) as websocket: while True: # 接收币安推送的原始数据 raw_data = await websocket.recv() data = json.loads(raw_data) # 这里写你自己的计算逻辑,比如算价格涨跌幅、指标之类的 processed_data = { "symbol": data["s"], "price": float(data["p"]), "timestamp": data["T"] } # 直接写入全局结果列表,单线程协程下无并发问题 result_list.append(processed_data) # 如果你需要定时清空或者转移结果,自己加逻辑就行 except Exception as e: # 连接异常等待1s重连,不影响其他交易对的连接 await asyncio.sleep(1) continue async def main(): # 批量启动所有300个交易对的协程任务 tasks = [handle_single_symbol(url) for url in WS_URLS] await asyncio.gather(*tasks) if __name__ == "__main__": asyncio.run(main())
优化提示
如果想要进一步降低连接开销,可以使用币安的组合流接口,将300个交易对的订阅合并到1个WebSocket连接中,比300个独立连接的资源占用更低,延迟更稳定。
注意事项
- 不要在协程的计算逻辑中加入阻塞式操作(比如同步的IO请求、
time.sleep等),否则会阻塞所有协程的运行 - 如果有CPU密集型的计算需求,可以将计算逻辑提交到
ProcessPoolExecutor中异步执行,避免阻塞事件循环 - 可以根据需求给
result_list加长度限制,避免内存占用过高
内容的提问来源于stack exchange,提问作者ghost
相关产品推荐
相关产品推荐

