Appearance
可观测性基础
可观测性用来回答系统运行时到底发生了什么。线上接口开始超时、用户反馈慢、发布后错误率升高——这些场景需要的不只是打开 Grafana 看一眼 CPU 曲线。
实践中通常看四类信息:指标看趋势和异常,日志看每次请求的具体报错,链路追踪看一次请求经过了哪些服务、慢在哪一段,事件看异常前后有没有发布、重启或配置变更。四类信号合在一起,才能从"CPU 正常"推进到"具体哪里出了什么问题"。
四类信号
指标是带时间戳的数值。CPU 使用率、内存可用量、磁盘剩余空间、接口 QPS、接口 P95 延迟、错误率、MySQL 连接数、Redis 命中率,都属于指标。因为格式统一,适合画曲线、做聚合、设告警阈值。指标回答的问题是"现在是否异常"和"趋势是否变坏"。不适合回答"单次请求为什么失败"——这是日志的范畴。
日志是系统或应用写出的文本记录,通常包含时间戳、级别、来源和具体内容。错误堆栈、请求参数、SQL 语句、业务错误码、用户 ID 这些细节,指标存不下,日志可以。线上排查时常见的用法是:先在指标上发现某个服务错误率升高了,再到日志里按服务名和时间范围过滤,看具体报错内容。日志里的关键字段(service、env、trace_id、status、level)设计得好,可以快速过滤出相关行。
链路追踪记录一次请求经过了哪些服务、每一段花了多少时间、错误出在哪个调用上。一个 Web 请求进来 → 订单服务 → 用户服务 → 订单服务读 MySQL → 调 Redis 缓存,整个过程跨多个服务,Trace 把这条调用链串成一棵树,每段叫一个 Span。指标上看到 P95 延迟尖刺时,如果 Trace 里显示"订单服务 → MySQL 查询"这一段耗时占比 95%,排查方向就能收窄到具体 SQL。
事件记录系统状态变化——发布、扩容、重启、配置变更、节点 NotReady、告警触发、告警恢复都属于事件。排查时经常先看指标异常出现的时间点,再去对照那段时间有没有发布或变更。用发布记录、审计日志、Kubernetes Events 来补时间线。
| 信号 | 常见内容 | 更适合回答的问题 |
|---|---|---|
| Metrics | CPU、内存、磁盘、QPS、延迟、错误率 | 是否异常,趋势是否变坏 |
| Logs | 应用日志、系统日志、访问日志、错误堆栈 | 当时具体报了什么 |
| Traces | Trace、Span、调用关系、单段耗时 | 慢请求卡在哪个服务或哪次数据库调用 |
| Events | 发布、重启、扩容、告警触发、告警恢复 | 异常前后发生了什么变化 |
排查链路
接口超时时,一个常见的排查顺序是:
- 先看指标——错误率和 P95 是不是在升高?全局的还是某个服务的?
- 再看事件——刚才有没有发布、重启或配置变更?
- 指标指向某个服务后,看它的日志——错误堆栈报了什么?
- 日志指向某次调用很慢,看链路追踪——慢在 MySQL、Redis 还是下游 HTTP?
这四类不用一次性全搭好。从指标告警开始——先知道什么时候出了问题;再补关键服务的日志采集——能查到报了什么错;链路追踪放到后面慢慢补——能还原慢请求的内部调用路径。
Prometheus 体系的指标链路
Prometheus 负责指标采集、存储和告警规则计算。整个流程分四段:
Exporter 把系统状态转成 Prometheus 认识的指标格式,暴露在 /metrics 路径上。Prometheus 按照配置文件里的地址定时去抓取,抓回来的样本写进本地 TSDB(时序数据库)。TSDB 针对按时间范围查询做了优化——查"最近 5 分钟 CPU"和"昨天下午 2 点到 3 点的 QPS"都很快。告警规则按固定间隔计算,如果一条规则持续满足条件(比如 CPU 连续高于 90%),就把状态变为 firing,推给 Alertmanager。Alertmanager 负责分组、静默、抑制和路由——多条告警要不要合成一条、维护窗口期间是否静默、按什么条件发给谁。
链路中的几个基本对象:
| 名词 | 说明 | 排查时看什么 |
|---|---|---|
| Exporter | 把系统状态转成 Prometheus 可抓的指标 | 端口是否通,/metrics 是否有内容 |
| Target | Prometheus 实际抓取的地址 | Targets 页面是否 UP |
| Scrape | Prometheus 定时去抓取一次的动作 | 最近一次抓取时间和耗时 |
| TSDB | Prometheus 本地时序数据库 | 保留周期、磁盘用量、查询性能 |
| Label | 指标上的键值标签 | 按实例、服务、环境等维度聚合 |
| Rule | 定时计算的告警规则 | 表达式是否能查到异常序列 |
| Alertmanager | 接收告警,负责分组、静默、抑制、通知 | 告警是否到了正确的接收人 |
Prometheus 默认是 Pull 模型——主动去各个目标抓指标,而不是等别人推过来。这意味着 Targets 页面能直接看到每个目标的最后一次抓取是否成功。某个目标出问题时,在 Prometheus 所在机器上 curl http://目标:端口/metrics 就能验证到 exporter 的网络和端口。短生命周期任务(定时备份脚本跑几秒就退出)用 Pull 可能等不到下次抓取,这类场景可以用 Pushgateway 作为补充中转。
实验环境
三台 Rocky Linux 9.7:
| 主机 | 角色 | 组件 |
|---|---|---|
192.168.10.11 | 监控节点 | Prometheus、Alertmanager、Grafana、Node Exporter |
192.168.10.12 | 被监控节点 | Node Exporter |
192.168.10.13 | 被监控节点 | Node Exporter |
这个环境覆盖从指标采集到告警通知的最短链路:主机指标采回来 → 写进 TSDB → PromQL 查询 → Grafana 看板 → 告警规则 → Alertmanager 通知。
Dashboard 和 Alert 的分工
看板是人主动去看的,告警是平台主动通知人的。看板上的指标可以放多一些——排查和观察时越全越好。告警规则要更克制,一条规则要能回答三个问题才算值得设:异常能被指标稳定表达吗、持续一段时间后还在吗、需要人来处理吗。磁盘 90% 满足这三条——很快就满了,不会自动缩小,人要去清或扩容。CPU 偶发冲到 80% 经常不满足——瞬间就回去了,放在看板上观察更合适。
| 对象 | 用法 |
|---|---|
| Dashboard | 排查和观察,指标可以多一些 |
| Alert | 发现需要处理的问题,规则要少而准 |
| Runbook | 告警后的检查步骤,几句话给出排查方向 |
| Event | 还原异常前后的发布、变更、重启记录 |
告警发太多是常见问题——十几条类似通知刷屏,值班的人慢慢就会习惯性忽略,一直忽略到真正重要的那条也漏掉。
四类信号的关联
指标、日志、链路追踪靠几个公共字段关联:
| 关联字段 | 作用 |
|---|---|
service | 指标、日志、Trace 都按服务名过滤 |
env / cluster | 区分环境和集群 |
instance / pod | 定位具体运行实例 |
trace_id | 从日志跳到 Trace,或从 Trace 反向找关联日志 |
| exemplar | 从指标曲线上的异常点跳到对应的 Trace |
Grafana 上看到一个 P95 尖刺,通过 exemplar 跳到几条代表性的慢 Trace,再拿着这些 TraceID 去日志里搜请求详情——这个关联能省掉"从指标发现异常 → 去日志系统按时间范围手工翻"的步骤。这个系列按"先搭指标和告警,再补日志和 Trace"的节奏展开。