2. 监控数据采集:Metrics、Logs、Traces 三大支柱
聊到监控数据采集,圈子里有个共识——光看指标不行,光看日志也不行。你得把 Metrics、Logs、Traces 这三样东西捏在一起,才能看清系统的全貌。我刚开始做调度系统监控那会儿,只盯着 CPU 和内存,结果线上出了故障,指标一切正常,业务却已经崩了半小时。嗯,从那以后,我再也不敢偏科了。
核心观点:Metrics 告诉你「出问题了」,Logs 告诉你「出了什么问题」,Traces 告诉你「问题出在哪一环」。三者缺一不可。
2.1 Metrics(指标)—— 系统的体温计
Metrics 说白了就是数字。它描述的是系统在某个时刻的状态,比如 QPS、延迟 P99、错误率、CPU 使用率。我习惯把 Metrics 分成三类:
- 工作负载指标:请求量、并发数、队列深度。调度系统里我最关注的是「待调度任务积压量」,这个数一涨,准没好事。
- 资源指标:CPU、内存、磁盘、网络。别只看平均值,要看 P99 和最大值。我曾经被「平均 CPU 50%」骗过,实际上有一台机器已经 100% 了。
- 业务指标:任务成功率、调度延迟、租户配额使用率。这些才是老板关心的。
采集 Metrics 的协议,现在主流是 Prometheus 的 Pull 模式。调度系统每个组件暴露一个 /metrics 端点,Prometheus Server 定期来拉。为什么不用 Push?你想想看,调度系统本身节点就多,如果每个节点都主动推数据,网络风暴先把你打趴下。
我的习惯:每个 Metrics 都要带三个标签——service(服务名)、instance(实例 ID)、region(区域)。没有标签的指标,排查问题时基本等于废纸。
2.2 Logs(日志)—— 系统的黑匣子
Metrics 告诉你「出问题了」,但说不出原因。这时候就得翻日志。日志是结构化的文本,每一行记录一个事件。我见过太多团队把日志当垃圾桶,什么乱七八糟的都往里写。结果真出故障时,几十 GB 的日志里捞不出一句有用的话。
好的日志应该长这样:
{
"timestamp": "2025-03-21T14:32:10.123Z",
"level": "ERROR",
"service": "scheduler-worker",
"trace_id": "abc123def456",
"message": "Task execution failed",
"context": {
"task_id": "task-98765",
"worker_id": "worker-03",
"error": "Connection timeout to executor"
}
}
看到了吗?关键信息全在:时间、级别、服务名、链路 ID、具体错误。我建议所有日志都采用 JSON 格式,方便后续接入 ELK 或 Loki 做全文检索。
避坑指南:我曾经遇到一个团队,日志里打了大量 DEBUG 级别的信息,结果磁盘写满,导致调度系统直接 OOM。记住:生产环境只开 WARN 和 ERROR,DEBUG 日志必须动态开关。
2.3 Traces(链路追踪)—— 系统的 X 光
Traces 解决的是「请求到底慢在哪」的问题。一个调度任务从提交到执行完成,中间可能经过 API 网关、调度器、队列、Worker、执行器。如果每个环节都慢 10ms,用户感知就是 50ms。没有链路追踪,你根本不知道瓶颈在哪。
我常用的 Trace 模型是 OpenTelemetry,它把一次请求抽象成一个 Trace,里面包含多个 Span。每个 Span 记录一个操作,比如「从队列拉取任务」「调用执行器接口」。Span 之间通过 parent_span_id 形成树状结构。
调度系统里,我建议至少给以下操作加 Span:
- 任务提交入口
- 任务排队等待
- 任务调度决策
- 任务执行调用
- 任务结果回写
这样一旦某个任务超时,你打开 Jaeger 或 Zipkin,一眼就能看出是调度器决策慢了,还是执行器响应慢了。
2.4 三大支柱的关系与整合
单独看 Metrics、Logs、Traces 都不够。你得把它们关联起来。怎么关联?靠 标签 和 ID。
我举个真实例子:
- Prometheus 告警:
task_latency_p99 > 5s(Metrics 发现问题) - 点开告警,看到异常的任务 ID 是
task-98765 - 去 Loki 搜
task_id=task-98765,发现日志里报了Connection timeout(Logs 定位原因) - 再拿
trace_id去 Jaeger 查,看到执行器调用阶段耗时 4.8s(Traces 定位环节)
你看,三步下来,问题根因就锁定了。这就是三大支柱整合的价值。
关键原则:Metrics 负责「告警」,Logs 负责「排查」,Traces 负责「定位」。不要指望一个工具干所有事。
2.5 数据采集架构总览
下面这张图是我自己总结的调度系统监控数据采集架构。你可以把它当成一个参考模板:
2.6 采集策略与避坑
数据采集不是把数据扔进去就完事了。我总结了几条铁律:
| 维度 | 推荐做法 | 常见坑 |
|---|---|---|
| 采集频率 | Metrics 15s 一次,Logs 实时,Traces 采样 10% | 频率太高把系统打满,频率太低错过故障 |
| 数据量控制 | Metrics 限制标签基数,Logs 设置轮转策略 | 标签爆炸导致 Prometheus OOM |
| 采样策略 | Traces 头部采样 + 错误全采样 | 全量采样成本高,尾部采样丢失关键链路 |
| 关联字段 | 统一 trace_id、service、instance | 字段名不统一,排查时对不上 |
我曾经踩过的坑:有一次调度系统频繁告警,我查了 Metrics 发现 Worker 的 CPU 飙升,但 Logs 里没有任何 ERROR。折腾了两小时才发现,是日志采集器 Filebeat 把磁盘 IO 打满了,导致 Worker 写日志都卡住。从那以后,我坚持把采集器进程和业务进程做资源隔离,并且给采集器单独设 CPU 限额。
2.7 小结
Metrics、Logs、Traces 这三样东西,你单独拎出来任何一个,都只能看到系统的一个侧面。只有把它们串起来,才能形成完整的可观测性。我个人习惯在 Grafana 里做一个统一的「故障排查面板」,左边放 Metrics 曲线,右边放关联的 Logs 和 Traces 入口。这样值班人员收到告警后,点一下就能开始排查,不用在多个系统之间来回跳。
嗯,数据采集这块就聊到这儿。记住:采集是基础,基础不牢,后面告警和自动化全是空中楼阁。