第九章:监控与告警系统

做市商系统跑起来之后,最怕什么?

怕半夜三点手机突然响了,但更怕的是——手机一直没响,早上到公司一看,系统已经挂了四个小时。

监控与告警,说白了就是给系统装上一套"神经系统"。哪里疼、哪里痒,得第一时间知道。我做了这么多年量化系统,见过太多"裸奔"上线的团队,结果无一例外都被市场教育了。

9.1 实时监控面板:你的系统仪表盘

实时监控面板,就是驾驶舱里的仪表盘。你得一眼能看出:

  • 当前持仓风险敞口有多大
  • 资金利用率是否合理
  • 各交易对报价延迟是否正常
  • 网络连接状态是否健康

我个人习惯把监控面板分成三个区域:

  • 顶部:全局指标,比如总敞口、总盈亏、系统健康度
  • 中部:各交易对详情,包括买卖价差、挂单深度、成交频率
  • 底部:系统资源,CPU、内存、网络延迟、数据库连接池

嗯,这里要注意一点:不要把所有数据都堆上去。我曾经见过一个团队,面板上放了80多个指标,结果真正出问题时,根本找不到关键信息。我建议核心指标控制在15个以内,其他的放到二级页面。

核心监控指标清单(我常用的):

  • 总敞口(Delta/Gamma/Vega)
  • 资金利用率(当前保证金/总资产)
  • 报价延迟(中位数、P99)
  • 成交率(挂单成交比例)
  • 系统错误率(每秒异常数)
  • 网络连接状态(交易所API延迟)

9.2 异常交易检测:别让bug变成亏损

做市商系统里,异常交易是最致命的。我遇到过最离谱的一次:一个浮点数精度问题,导致系统在某个价格位上反复报单撤单,一晚上产生了200多万次无效请求,交易所直接把我们IP封了。

异常检测,我一般分三层:

  • 第一层:规则引擎——硬性阈值检查。比如单笔成交金额超过总资产的5%,直接报警并暂停该交易对。
  • 第二层:统计检测——基于历史数据的异常识别。比如某个交易对的成交频率突然飙升到均值的10倍以上,触发告警。
  • 第三层:行为分析——检测策略行为是否异常。比如连续撤单超过50次,或者报价价差突然收窄到正常值的1/10。

我曾经踩过一个坑:只做了第一层规则引擎,结果市场剧烈波动时,所有阈值都被突破,告警刷屏,反而把真正的问题淹没了。后来我加上了"告警抑制"机制——同一类告警5分钟内只发一次。

避坑指南:

我曾经把告警阈值设得太敏感,结果每天收到上千条告警,团队直接麻木了。后来我改成"分级告警":

  • P0(致命):系统宕机、资金异常 → 电话+短信
  • P1(严重):策略行为异常、网络中断 → 即时消息+邮件
  • P2(警告):指标偏离正常范围 → 邮件+日志
  • P3(信息):日常统计报告 → 仅日志

9.3 性能监控:别让延迟吃掉利润

做市商的核心竞争力是什么?说白了就是速度。你比别人慢1毫秒,可能就抢不到最优报价。

性能监控,我重点关注三个维度:

  • 报价延迟:从行情到达 → 策略计算 → 报单发出,整个链路耗时。我要求P99延迟不超过50ms。
  • 成交确认延迟:从报单到收到成交回执的时间。如果超过200ms,说明网络或交易所端有问题。
  • 系统吞吐量:每秒能处理多少笔报单和撤单。这个指标决定了你能同时做多少个交易对。

我记得有一次,系统突然出现间歇性延迟,排查了两天才发现是日志库的锁竞争导致的。从那以后,我强制要求所有IO操作都走异步队列,并且日志写入不能阻塞主流程。

// 性能监控的核心代码片段(伪代码)
class PerformanceMonitor {
    private:
        std::atomic<int64_t> total_orders;
        std::atomic<int64_t> total_latency_us;
        
    public:
        void record_order(int64_t latency_us) {
            total_orders++;
            total_latency_us += latency_us;
            // 记录P99延迟
            if (latency_us > p99_threshold) {
                alert("High latency detected: " + latency_us + "us");
            }
        }
        
        double get_avg_latency_ms() {
            return total_latency_us / (total_orders * 1000.0);
        }
};

9.4 告警规则引擎:让系统自己"说话"

告警规则引擎,说白了就是一套"如果...就..."的逻辑。但真正好用的引擎,得支持:

  • 组合条件:比如"报价延迟 > 100ms 且 成交率 < 50%" 才告警,避免单一指标误报
  • 时间窗口:比如"连续5分钟内,错误率超过1%" 才触发,而不是单次抖动就报警
  • 动态阈值:根据市场波动自动调整告警阈值。比如波动率低时,价差超过0.1%就告警;波动率高时,价差超过0.5%才告警

我建议用JSON或YAML来配置规则,方便运维人员修改,不用改代码。

{
  "rules": [
    {
      "name": "报价延迟过高",
      "condition": "avg_latency_ms > 100 AND duration_minutes > 5",
      "severity": "P1",
      "actions": ["send_sms", "send_wechat"]
    },
    {
      "name": "资金异常变动",
      "condition": "balance_change_percent > 10 AND time_window_minutes < 1",
      "severity": "P0",
      "actions": ["call_oncall", "pause_trading"]
    }
  ]
}

重要提醒:

告警规则不是越多越好。我见过一个团队配置了200多条规则,结果真正出问题时,告警信息被淹没在"误报"里。我的经验是:先配10条最核心的,跑一个月再逐步优化。另外,一定要有"告警自愈"机制——比如网络抖动导致的短暂延迟,系统自动重试后恢复正常,就不需要通知人。

9.5 监控系统架构图

下面这张图,是我个人比较推荐的监控系统架构。它把数据采集、存储、分析、告警分成了四个独立模块,方便扩展和维护。

监控与告警系统架构图 数据采集层 行情数据 交易数据 系统指标 日志数据 数据处理层 实时流处理 数据清洗 指标计算 聚合统计 存储与分析层 时序数据库 告警历史 趋势分析 报表生成 告警与展示层 实时面板 告警通知 自愈脚本 人工介入

这张图里,数据从底层采集上来,经过清洗和计算,存入时序数据库。告警引擎实时扫描数据,一旦匹配规则就触发通知。我个人习惯把"自愈脚本"也放在告警层——比如检测到某个交易对报价延迟过高,自动重启该交易对的报价进程,而不是直接通知人。

9.6 实战经验总结

最后,分享几个我踩过的坑:

  • 监控本身也会出问题:我曾经遇到过监控系统自己挂了,但没人知道。后来我加了一个"心跳检测"——监控系统每隔5分钟给自己发一条告警,如果收不到,说明监控挂了。
  • 告警疲劳是真实存在的:团队每天收到几百条告警,最后大家都麻木了。我建议每周复盘一次告警规则,把那些"从来没触发过"或者"触发后没人处理"的规则删掉。
  • 不要忽视日志:很多问题在告警触发之前,日志里已经有征兆了。我要求所有核心模块都打结构化日志(JSON格式),方便事后回溯。

嗯,监控与告警系统,说白了就是给系统买了一份"保险"。平时觉得没用,真出事的时候,它能救你一命。

交易系统化学习资料 微信Strategy888888