2. 监控体系设计原则:黄金信号与分层采集

做高频交易运维这些年,我踩过最大的坑就是——监控数据铺天盖地,但系统崩了却找不到根因。

你想想看,一个交易系统每秒处理几万笔订单,延迟波动个几微秒可能就是几百万的损失。这时候如果监控体系设计得不好,你连问题出在哪都不知道。

所以今天咱们聊聊监控体系的设计原则。说白了,就是三个黄金信号加三层数据分层。

2.1 黄金信号:延迟、吞吐量、错误率

我个人习惯把这三个指标称为「保命三件套」。为什么是它们?

  • 延迟(Latency):订单从进门到出门花了多久
  • 吞吐量(Throughput):单位时间能处理多少订单
  • 错误率(Error Rate):处理失败的订单占比

这三个指标互相牵制。吞吐量上去了,延迟可能就飙了。错误率高了,往往意味着系统快扛不住了。

核心原则:三个信号必须同时监控,缺一不可。

2.1.1 延迟的定义与采集

延迟在高频交易里分很多种。我一般关注这几个维度:

  • 网络延迟:从网卡到应用层的时间
  • 处理延迟:业务逻辑执行的时间
  • 排队延迟:请求在队列里等待的时间
  • 端到端延迟:从客户端发起到收到响应的总时间

采集方式上,我建议用 eBPF 或者 DPDK 的硬件时间戳。软件打点的方式在高频场景下误差太大。

我的经验:曾经有个项目,我们用软件时间戳测延迟,结果发现比硬件时间戳差了将近 5 微秒。5 微秒在高频交易里是什么概念?够一个订单从上海跑到深圳再回来了。

2.1.2 吞吐量的定义与采集

吞吐量不只是看每秒处理多少笔。我习惯拆成:

  • 订单接收吞吐量:网卡每秒能收多少订单
  • 订单处理吞吐量:业务层每秒能处理多少
  • 订单发送吞吐量:交易所网关每秒能发多少

采集时要注意 采样周期。别用 1 秒的平均值,那会掩盖毛刺。我一般用 100 毫秒的滑动窗口。

// 伪代码示例:滑动窗口吞吐量计算
class ThroughputCounter {
    private:
        deque<Timestamp> window;
        const int WINDOW_MS = 100;
    
    public:
        void record() {
            auto now = get_hardware_timestamp();
            window.push_back(now);
            // 清理过期数据
            while (!window.empty() && 
                   (now - window.front()) > WINDOW_MS) {
                window.pop_front();
            }
        }
        
        double get_throughput() {
            return window.size() / (WINDOW_MS / 1000.0);
        }
};

2.1.3 错误率的定义与采集

错误率不是简单的「成功/失败」二分类。我把它分成:

  • 业务错误:订单被交易所拒绝(比如价格超出范围)
  • 系统错误:内部处理异常(比如内存分配失败)
  • 超时错误:超过预期时间未收到响应

避坑指南:我曾经遇到过一个案例,错误率监控只报了「系统错误」,结果发现是网络丢包导致的超时。从那以后,我把超时单独拎出来监控了。

2.2 监控数据的分层架构

监控数据不能一锅烩。我习惯分三层:

  1. 基础设施层:服务器、网络、存储
  2. 中间件层:消息队列、数据库、缓存
  3. 应用层:业务逻辑、交易策略

为什么要分层?因为不同层的问题,排查思路完全不同。

2.2.1 基础设施层监控

这一层是地基。地基不稳,上面再好的房子也白搭。

监控项 采集方式 告警阈值
CPU 使用率 /proc/stat > 80% 持续 30 秒
内存使用率 /proc/meminfo > 90%
网络丢包率 ethtool -S > 0.01%
磁盘 IO 延迟 iostat > 10ms

嗯,这里要注意:网络丢包率在高频交易里是红线。哪怕 0.01% 的丢包,都可能导致订单丢失。

2.2.2 中间件层监控

中间件是系统的「血管」。血管堵了,血液就流不动了。

  • 消息队列:队列深度、消费延迟、生产速率
  • 数据库:连接数、慢查询、锁等待
  • 缓存:命中率、过期率、内存使用

我的习惯:中间件层的监控,我特别关注「队列深度」。曾经有一次,消息队列深度从 100 涨到了 10000,我们才发现消费端挂了。如果早点发现队列深度异常,至少能提前 5 分钟恢复。

2.2.3 应用层监控

这一层最复杂,也最贴近业务。

  • 交易延迟:每个订单的处理耗时分布
  • 策略状态:策略是否在运行、参数是否正常
  • 订单流:订单的完整生命周期追踪

应用层监控我建议用 分布式追踪。每个订单打一个 trace ID,从接收到成交,全程追踪。

2.3 黄金信号与分层的关系

这三个黄金信号,在每个层级都有不同的表现。

举个例子:

  • 基础设施层延迟高,可能是网络问题
  • 中间件层延迟高,可能是队列堵塞
  • 应用层延迟高,可能是策略计算太慢

所以排查问题时,我习惯从下往上查。先看基础设施,再看中间件,最后看应用层。

核心思路:黄金信号是「症状」,分层是「解剖图」。症状告诉你哪里疼,解剖图告诉你疼在哪一层。

2.4 本章知识体系

下面这张图,是我自己总结的监控体系设计框架。你可以把它当成一个检查清单:

高频交易监控体系设计框架 黄金信号(三大指标) 延迟(Latency) 吞吐量(Throughput) 错误率(Error Rate) 监控数据分层 应用层 交易延迟 | 策略状态 | 订单流追踪 中间件层 消息队列深度 | 数据库连接 | 缓存命中率 基础设施层 CPU/内存 | 网络丢包 | 磁盘IO延迟 排查路径:从下往上,先基础设施,再中间件,最后应用层

这张图的核心逻辑很简单:三个黄金信号贯穿三层架构。每一层都要采集这三个信号,但采集的侧重点不同。

最后说一句:监控体系不是一蹴而就的。我刚开始做的时候,也是先搭了个简陋的架子,然后慢慢补。关键是先把「保命三件套」跑起来,其他的可以后面再优化。

专注资料整理