auto_trade_sys/docs/WebSocket共用与限频评估.md
薇薇安 43e993034f feat(redis_integration): 支持多进程共用市场数据流
在 `binance_client`、`kline_stream`、`book_ticker_stream` 和 `ticker_24h_stream` 中引入 Redis 缓存支持,允许 Leader 进程写入数据,其他进程从 Redis 读取,提升数据获取效率。更新了相关逻辑以确保在多进程环境下的稳定性和一致性,同时增强了异常处理和日志记录,确保系统的可追溯性。
2026-02-16 17:44:10 +08:00

114 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# WebSocket 共用与币安限频评估
## 一、币安合约 WS 限制(摘要)
- **Base URL**`wss://fstream.binance.com`
- **单 stream**`/ws/<streamName>`
- **组合 stream**`/stream?streams=/<streamName1>/<streamName2>/...`
- **单连接最多订阅****1024 个 Streams**
- **订阅限速****每秒最多 10 条订阅消息**,超限会断连;**反复断连的 IP 可能被屏蔽**
- **连接有效期**:单连接不超过 24 小时,需断线重连
- **Ping/Pong**:服务端约 3 分钟发 ping客户端需在 10 分钟内回复 pong当前 aiohttp heartbeat 已满足)
---
## 二、当前系统 WS 使用方式(按进程)
当前为 **一进程一账户**(如 supervisor 按 `ATS_ACCOUNT_ID` 起多个 trading_system 进程),每个进程内:
| 用途 | 连接数/进程 | 订阅内容 | 是否公开 | 可否多账户共用 |
|------|-------------|----------|----------|----------------|
| **UserDataStream** | 1 | listenKey订单/持仓/余额) | 否(需 listenKey | **否**,每账户必须独立 |
| **Ticker24hStream** | 1 | `!ticker@arr`(全市场 24h ticker | 是 | **可共用**,全市场一份即可 |
| **BookTickerStream** | 1 | `!bookTicker`(全市场最优买卖) | 是 | **可共用**,全市场一份即可 |
| **KlineStream** | 1 | `/stream` + 动态 `SUBSCRIBE``<symbol>@kline_<interval>` | 是 | **可共用**,按需订阅,单连接 ≤1024 streams |
| **持仓价格监控**position_manager | **每持仓 1 条** | 每连接 `/ws/<symbol>@ticker` | 是 | **可共用**,可合并为一条组合流 |
即:**每账户 4 条固定连接 + 持仓数个单独连接**。
---
## 三、多账户时的连接与订阅量(当前架构)
设账户数为 **N**,单账户最大持仓数为 **M**(如 10
- **UserDataStream**N 条(每账户 1**不能省**
- **Ticker24hStream**N 条 → 若共用为 **1 条**
- **BookTickerStream**N 条 → 若共用为 **1 条**
- **KlineStream**N 条,每连接动态订阅若干 `symbol@kline_interval` → 若共用为 **1 条**,总 streams 数为「所有账户用到的 (symbol, interval) 并集」
- **持仓监控**N × M 条(每持仓一个 `/ws/<symbol>@ticker`)→ 若合并为一条组合流,为 **1 条连接**streams 数为「所有账户持仓的 symbol 并集」,且 **≤1024**
**当前是否超限:**
- **1024 streams/连接**:单条 KlineStream 当前按「扫描/策略用到的 symbol×interval」订阅通常几十小几百级远低于 1024持仓监控若合并为一条组合流symbol 数一般也远小于 1024。**正常使用不会超**。
- **10 条订阅/秒**KlineStream 在扫描时可能对多个 symbol×interval 连续调用 `subscribe`,若并发高会短时间多发订阅消息,有**超过 10 条/秒**的风险,存在被断连、进而 IP 被限的风险。**需要限速**(见下文实现)。
---
## 四、可共用的流与建议
### 1. 强烈建议共用(公开、全市场一份即可)
- **Ticker24hStream**`!ticker@arr`
- 全市场 24h 行情,与账户无关。
- **建议**:单机多进程时,可由一个「行情进程」或主进程单独起 1 条连接,写入 Redis/共享缓存,其他进程只读缓存;或若已用 Redis 等共享缓存,仅一个进程负责拉 WS 并更新缓存。
- **BookTickerStream**`!bookTicker`
- 全市场最优买卖,与账户无关。
- **建议**:同上,共用 1 条连接 + 共享缓存。
### 2. 建议共用(减少连接与 stream 总数)
- **KlineStream**`<symbol>@kline_<interval>`
- 按 (symbol, interval) 动态订阅,单连接最多 1024 streams。
- 多账户共用 1 条连接时,订阅集合为「各账户用到的 (symbol, interval) 并集」,通常仍远小于 1024。
- **建议**:单机多进程时,可只在一个进程内起 KlineStream其他进程通过 Redis/共享内存读 K 线缓存或部署一个共享「K 线 WS 服务」供多进程使用。
- **持仓监控**`<symbol>@ticker`
- 当前实现为「每持仓 1 条 `/ws/<symbol>@ticker`」,多账户×多持仓会变成 N×M 条连接。
- **建议**:改为**一条组合流**`/stream?streams=s1@ticker/s2@ticker/...`,把所有需要监控的 symbol 放在一起,总 symbol 数 <1024 即可多账户可共用这一条连接订阅所有账户持仓 symbol 的并集」),每个账户只消费自己关心的 symbol 即可
### 3. 不能共用
- **UserDataStream**listenKey
- 与账户绑定每账户独立 listenKey独立连接。**必须每账户 1 条连接**。
---
## 五、限频与实现建议
### 1. 订阅消息 ≤10 条/秒(必须遵守)
- **KlineStream** `subscribe(symbol, interval)` 时向同一连接发送 SUBSCRIBE
- 若扫描阶段并发请求多个 symbol×interval会在短时间连续发送多条订阅容易超过 **10 条/秒**
- **实现** KlineStream 内做**订阅限速**例如维护最近 1 秒内已发送的订阅次数」,若已达 10 次则 sleep 1 后再发或批量排队按每秒最多 810 条发送
- 已在代码中为 KlineStream 增加限速逻辑见下节)。
### 2. 单连接 1024 streams
- 当前 KlineStream 与持仓监控的 stream 数量均远低于 1024只需在后续若预订阅大量 symbol×interval 或大量持仓时确保单连接订阅数 1024 即可可做订阅数统计与上限检查)。
### 3. 连接 24 小时
- 现有各 WS 均有断线重连满足不超过 24 小时的文档要求保持即可
---
## 六、结论与风险
| 项目 | 当前是否可能超限 | 说明 |
|------|------------------|------|
| 单连接 1024 streams | | 当前 K 线与持仓监控订阅量远低于 1024 |
| 10 条订阅/ | **是(有风险)** | KlineStream 扫描时可能短时大量 subscribe已加限速 |
| 连接数 | | 多账户时连接数线性增长共用后可显著下降 |
| 24h / Ping-Pong | | 已重连 + heartbeat |
**已实现:**
1. **KlineStream 订阅限速**发送 SUBSCRIBE 时控制在 10 /
2. **多进程/多账户共用 Ticker24h、BookTicker、KlineStream**
- 使用 Redis 选主`market_ws_leader` **Leader** 进程建立上述三条 WS 连接并写入 Redis
- Leader 进程不建这三条连接通过 **Redis 刷新任务**Ticker24h/BookTicker 2 秒从 Redis 拉取 **get_klines 时读 Redis** 获取数据
- 配置项 `USE_SHARED_MARKET_WS`默认 true Redis 时启用共用关闭则每进程独立建连接
3. **持仓监控**仍为每进程按持仓建多条 `/ws/<symbol>@ticker`后续可改为单连接组合流并共享未实现)。