收藏
0
0
分享
举报
·7 小时前发布·74次阅读

HTTP轮询还是WebSocket?不同行情场景下的API选型思

独立开发商业增长付费用户

去年做一个美股盯盘小工具,图省事用了REST接口每两秒轮询一次。跑了一个礼拜,某天盘中突然收到云服务商发来的流量告警——单日请求量冲到了三十多万次。更麻烦的是,那几天特斯拉财报前后波动剧烈,轮询间隔内价格跳了好几个档位,数据完全对不上。

后来才意识到,行情接入这件事,选错协议比写错代码更致命。

两种协议的底层逻辑,HTTP轮询像定时去信箱取信。客户端每隔几秒发一次请求,服务端返回当前快照。简单、直观,随便一个人半小时就能调通。WebSocket是一条一直开着的管道,服务端有数据就主动推过来,行情自己往屏幕上蹦。

听起来WebSocket肯定更好?不一定。

轮询的适用场景

做日线级别的回测,或者15分钟K线的监控,轮询完全够用。一天才96根15分钟线。这类场景对延迟不敏感,差个两三秒没人在意。

还有那些只开放REST端口的免费接口。练手阶段、验证想法,轮询没毛病。

去年做的一个价差监控脚本,用的是十秒一次的轮询。价差通常持续几十秒才变化,十秒的延迟完全够用。代码写起来也省心,不用处理重连、心跳这些麻烦事。

WebSocket真正发力的地方

Tick级别的高频监控,或者毫秒级响应要求的逻辑,必须上WebSocket。

做某个实验的时候试过轮询,每秒拉一次,结果发现拿到的价格和实际成交价经常差好几个点。原因是市场波动快的时候,一秒内能变化几十次,轮询抓到的只是那一瞬间的快照,中间的重要波动全丢了。换成WebSocket推送,逐笔Tick进来,能看到完整的价格变化轨迹。

另一个场景是监控几十个交易对。用轮询的话,每个交易对都要单独请求,并发量上来压力很大。WebSocket一次订阅一堆品种,所有数据走同一条连接,效率高太多了。

完整的Python接入逻辑大致如下:


import websocket

import json

import uuid

TOKEN = "your_token"

url = f"wss://quote.alltick.co/quote-stock-b-ws-api?token={TOKEN}"

def on_open(ws):

    trace_id = str(uuid.uuid4())

    subscribe_msg = {

        "cmd_id": 22004,

        "seq_id": 123,

        "trace": trace_id,

        "data": {

            "symbol_list": [

                {"code": "AAPL.US"},

                {"code": "MSFT.US"}

            ]

        }

    }

    ws.send(json.dumps(subscribe_msg))

ws = websocket.WebSocketApp(url, on_open=on_open)

ws.run_forever()

怎么选才不纠结

一个简单的判断标准:超过三秒能接受,轮询就够了;一秒以内甚至毫秒级,必须WebSocket。

还要看数据密度。同一时间只盯一只股票,轮询勉强能行。同时盯几十个品种,不用WebSocket就是给自己找麻烦。

工程里还有一种折中方式。主链路用WebSocket拿实时数据,旁边挂一个轮询接口做备份。WebSocket万一断线,轮询立即顶上,保证数据流不中断。代码复杂度上去了,但换来的是稳定性。

回到开头那个盯盘工具,后来改成了WebSocket加本地缓存。连接只维持一条,行情推过来直接写缓存,前端需要时再读。云服务费用降了九成,数据延迟从两秒缩到了两百毫秒以内。

技术选型这件事,没有绝对的好坏。适合当下场景的,就是对的。先算清楚自己需要多快的数据,再做决定。

讨论 (0)

    关于作者

    心得体会

    这家伙很懒,什么都没留下

    Solo 独立开发者社区support@solo.xin
    关于社区隐私政策用户协议商务合作友情链接订阅更新(RSS)投稿赞助

    © 2023 SOLO · 为独立开发者而生