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 监控数据的分层架构
监控数据不能一锅烩。我习惯分三层:
- 基础设施层:服务器、网络、存储
- 中间件层:消息队列、数据库、缓存
- 应用层:业务逻辑、交易策略
为什么要分层?因为不同层的问题,排查思路完全不同。
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 本章知识体系
下面这张图,是我自己总结的监控体系设计框架。你可以把它当成一个检查清单:
这张图的核心逻辑很简单:三个黄金信号贯穿三层架构。每一层都要采集这三个信号,但采集的侧重点不同。
最后说一句:监控体系不是一蹴而就的。我刚开始做的时候,也是先搭了个简陋的架子,然后慢慢补。关键是先把「保命三件套」跑起来,其他的可以后面再优化。