做外汇行情API对接的团队,到了一定阶段都会被同一个问题卡住:WebSocket订阅到底能扛多少货币对?
我第一次认真面对这个数字,是在一次“把产品里28个主要货币对扩展成61个”的需求评审上。当时有同事非常笃定,说一个连接订阅一百多个货币对肯定没问题,WebSocket是长连接,不像REST要频繁握手;另一个同事坚持说行情推送是高频消息,货币对数量翻倍意味着推送量直接翻倍,很可能把连接撑爆。两人谁也说服不了谁,最后压测任务落到了我头上。这篇文章不是要给你一个绝对的官方数字,而是想把我自己从单货币对推到上百货币对的实测过程、计算逻辑和踩坑记录完整写下来,给同样在接外汇行情API、用WebSocket做实时订阅的人一个可复用的判断框架。
先说结论。WebSocket订阅能扛多少货币对,本质上不是一个由“连接上限”决定的数字,而是由三个指标共同决定的:连接数上限、单位时间消息密度、以及客户端服务端的处理速度。货币对数量只是输入参数,真正决定你卡在哪个环节的,是这三个指标里先被触顶的那一个。
1. “扛多少货币对”背后其实问的是三个指标
1.1 连接数、消息密度、处理速度是三道不同的坎
很多人在评估WebSocket容量时,第一反应是去看服务器最大连接数。这个思路在“用户同时在线”场景下是对的,但在外汇行情订阅场景下很容易产生误判。
我用一个例子说明:假设你的行情服务基于Node.js,单进程能撑住数万个空闲连接,这看起来很多。但外汇行情每秒都在产生tick数据,连接上是有持续流量的。一个连接在空闲时几乎不消耗CPU,但一个不断接收数据的连接就不一样了,每一条消息都要走完“接收→解析→分发”的完整链路。这时候,连接数上限早就不是瓶颈,消息密度才是。
消息密度又可以拆成两个变量:单个货币对的tick频率,以及你订阅的货币对总数。订阅列表从10对扩到50对,如果每个货币对的推送频率都是每秒5次,那消息量就是5倍。这个增长是线性的,看似好算,但外汇行情最大的特点就是不均匀,欧美盘重叠时段和新闻发布瞬间,tick频率可能瞬间放大10倍以上。所以你不能用“平均每秒几条”来估算,必须用“峰值每秒几条”来做预算。
处理速度就更好理解了:服务端推送再快,客户端解析不过来,消息就会在缓冲区堆积,堆积多了就会内存上涨、延迟拉高,最后触发心跳超时被服务端断开。很多“WebSocket扛不住”的现象,根因不在带宽,而在客户端处理不过来。
1.2 一个货币对的tick频率波动到底有多大
我觉得有必要把tick频率的波动说透,因为这个数据直接决定后续一切计算。
以EUR/USD这种全球流动性最强的货币对为例。在亚洲早盘比较清淡的时候,一秒钟可能只推送1~2次;欧洲时段进入活跃期,每秒能到5~10次;遇到美国非农数据、美联储利率决议这类事件,一秒钟推送几十次甚至上百次都不是新闻。GBP/USD、USD/JPY这类主流货币对的情况类似,只是数字会稍微小一点。
交叉盘和奇异货币对就完全不同了。EUR/GBP、AUD/NZD这类流动性一般的品种,平时可能两三秒才有一条tick,即使进入消息行情,也远达不到主流货币对的频率。所以当你听到别人说“我这个API订阅了200个货币对很流畅”的时候,要先问一句:你订阅的是流动性很好的28个主要货币对,还是把那些半天都不动一下的奇异货币对也算上了?这两者的负载差着一个数量级。
1.3 服务端对订阅数量往往会做隐性限制
还有一个很多人没注意到的坑:不少外汇行情API服务端,并不会真的允许你在一个连接里无限订阅。
有些平台有明确的单连接订阅上限,比如限制每个连接最多订阅100个或200个交易品种;有些平台不限制订阅数量,但会针对单个连接的带宽、消息速率做流控,超过阈值就直接断开并提示重连。更隐蔽的是,部分平台的文档写得很含糊,真正的限制只有在你订阅超过某个数量后才会触发,而且表现方式不是报错,而是“某几个货币对突然不推送了”或者“连接被静默断开”。
这类限制很难通过阅读文档发现,只能靠压测去试。我建议你在正式做容量规划之前,先确认三件事:平台是否有单连接订阅上限、是否有带宽或速率流控、断开连接时是否会返回明确错误码。这三件事不清楚就上线,后面排查问题的成本会非常高。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
