1. 课程导入
在真实交易系统中,故障不是“是否发生”的问题,而是“何时发生、以何种方式发生”的问题。行情断流、网关重启、数据库主从切换、策略进程崩溃、消息重复或乱序,都可能在毫秒级影响订单与持仓。本课程聚焦三个紧密关联的能力:实盘故障恢复、事件回放与状态重建。它们共同回答一个核心问题:当系统偏离正常轨迹后,如何以可验证的方式回到正确状态,并继续安全运行。
学习目标
- 理解实盘故障恢复的边界:区分“进程恢复”“连接恢复”“业务状态恢复”与“资金/持仓一致性恢复”。
- 掌握事件回放的基本方法:基于日志、消息队列或快照,按时间与因果顺序重放事件。
- 能够设计状态重建流程:从快照加载、增量回放、校验对账到恢复对外服务。
- 建立可观测与可验证意识:用指标、日志、对账结果证明恢复正确,而非“看起来正常”。
- 识别常见误区:把重启当恢复、把回放当重放、忽略幂等与重复事件、缺少恢复演练。
核心概念:三条主线与一个闭环
故障恢复关注“如何从异常中恢复服务”;事件回放关注“如何按历史事实重新驱动系统”;状态重建关注“如何从事件与快照中重新计算出正确状态”。三者构成一个闭环:故障触发恢复,恢复需要回放,回放服务于状态重建,重建结果又反过来验证恢复是否成功。
关键等式:正确状态 = 可信快照 + 有序事件回放 + 幂等处理 + 对账校验。
在交易场景中,状态通常包括:订单状态机、持仓数量、可用资金、冻结资金、成交回报、行情订阅关系等。事件则包括:行情快照、逐笔成交、订单请求、撤单请求、成交回报、系统控制指令。回放不是简单“再跑一遍”,而是要在受控环境中重现因果链,确保同一事件序列产生同一状态结果。
方法流程:从故障到恢复的六步法
- 冻结与隔离:停止新订单进入,隔离故障节点,防止状态继续恶化。
- 定位与定界:确认故障类型(连接、进程、数据、逻辑),确定影响范围与时间窗口。
- 选择恢复点:找到最近的可信快照或检查点,确定回放起点。
- 事件回放:按序重放事件,处理重复与乱序,保证幂等。
- 状态校验:与交易所回报、数据库、风控系统对账,确认订单、持仓、资金一致。
- 灰度恢复:逐步放开流量,持续监控,确认稳定后完全恢复。
提示:恢复点不是越早越好。过早回放会增加计算量与不确定性;过晚则可能丢失关键事件。应结合快照频率、事件保留窗口与业务容忍度选择。
案例/场景:行情断流后的持仓重建
假设某策略进程因行情网关断流而崩溃,重启后本地持仓与交易所不一致。此时不能直接下单,而应执行以下流程:
# 1. 停止策略下单
systemctl stop strategy-engine
# 2. 从最近快照加载状态
load_snapshot --file /data/snapshots/2025-03-21T09-30-00.json
# 3. 回放断流窗口内的事件
replay_events --from 2025-03-21T09:30:00 --to 2025-03-21T09:45:00 \
--source kafka://market-events --mode ordered --idempotent
# 4. 对账校验
reconcile --orders --positions --cash --exchange-binance
# 5. 校验通过后灰度恢复
systemctl start strategy-engine -- --rate-limit 10%
该场景中,回放必须保证事件顺序与真实发生顺序一致,且订单请求、撤单、成交回报要按因果链处理。若忽略幂等,重复的成交回报可能导致持仓翻倍。
误区与复盘
| 常见误区 | 后果 | 正确做法 |
|---|---|---|
| 把进程重启当作故障恢复 | 状态未重建,继续错误下单 | 重启后必须执行回放与对账 |
| 回放时忽略事件顺序 | 状态机错乱,订单状态不一致 | 按时间戳与因果序回放 |
| 未做幂等处理 | 重复事件导致持仓/资金翻倍 | 事件ID去重,操作幂等 |
| 缺少对账环节 | “看起来正常”但实际有偏差 | 与交易所、数据库多方对账 |
| 没有恢复演练 | 真实故障时手忙脚乱 | 定期演练,记录恢复时间 |
警告:实盘恢复中最危险的不是“恢复失败”,而是“恢复后以为成功”。任何未经过对账校验的状态重建,都不应直接接入真实资金与订单。
本课程后续将围绕这三个能力展开:从事件日志设计、快照策略、回放引擎实现,到状态机重建、对账体系与恢复演练。掌握它们,你才能在实盘故障面前保持可控、可验证、可恢复。