Java 微服务监控与日志:Prometheus + Grafana + ELK + SkyWalking + Loki 全链路可观测性实战
Java Web 微服务系列 · 第 9 篇 · 监控与日志 阅读时长:约 50 分钟 本文写于 2026 年 6 月
引子:凌晨 3 点的告警风暴
2021 年某日凌晨 3 点 17 分,我的手机开始震动。
不是一条告警——是 73 条。手机屏幕上挤满各种颜色的推送:钉钉群、飞书、Slack、Prometheus AlertManager、邮件、企业微信……每一条都"重要紧急",但每一条都没说清"到底哪里出了事"。
我当时所在的电商平台正处于大促预热期,技术栈是 200+ Spring Cloud 微服务 + 30+ 中间件。我冲到电脑前看到的景象是:
- Grafana 大盘上 17 个核心指标 全是红的:CPU 95%、P99 3.2s、错误率 8.7%、JVM FullGC 频繁、Kafka 消费积压 12 万
- Kibana 上日志查询 慢到 30 秒返回结果(ES 集群 IO 100%)
- SkyWalking 链路追踪 显示"调用链断层"——只有 30% 的请求能查到完整 trace
- SRE 群里 8 个工程师对着 73 条告警吵成一团,没人能说"先看哪条"
真正的故障点在 12 分钟后才被定位:一个非核心的"商品评论服务"在慢 SQL,把 MySQL 连接池占满,进而拖垮了订单服务,最终引发全链路雪崩。
事后复盘,技术总监问了一个让我深思的问题:
“我们有 7 套监控系统、5 套告警通道、3 套日志平台、2 套链路追踪系统。为什么出了事反而不知道出了什么事?”
那晚之后,我们花了 3 个月做"可观测性体系重构",把 17 套工具收敛成 “1+1+1+1+N” 的标准架构:
- 1 个统一指标层:Prometheus + Grafana
- 1 个统一日志层:Loki + Promtail(业务日志)+ ELK(合规日志)
- 1 个统一链路层:SkyWalking
- 1 个统一告警层:Alertmanager + 告警分级 + On-Call
- N 个自动采集:Java Agent / Sidecar / DaemonSet
到 2025 年回看,那次重构救了我们无数次。可观测性不是"装一套 Prometheus 就够了"——它是一套完整的工程实践。
本文要回答的问题:
- Metrics / Logging / Tracing 三大支柱如何统一?
- Prometheus / Grafana / ELK / SkyWalking / Loki 怎么选型、怎么落地?
- 自动采集、自动告警、自动恢复的全链路怎么搭?
- 告警治理怎么做?怎么避免"凌晨 73 条告警"的灾难?
全文 10000+ 字,一次把可观测性体系讲透。
一、核心概念:把"可观测性"掰开
谈具体技术前,先把 3 个常被混用的术语定义清楚——很多团队的"监控"压根不是可观测性。
1.1 三个支柱:Metrics / Logging / Tracing
可观测性(Observability) 源自控制论,指通过系统外部输出推断内部状态的能力。在微服务领域,它由 3 大支柱 构成:
| 支柱 | 回答什么问题 | 典型数据 | 典型工具 | 数据特征 |
|---|---|---|---|---|
| Metrics(指标) | 系统的整体状态怎样? | CPU、QPS、P99、错误率 | Prometheus / Grafana | 数值型、低基数、高频 |
| Logging(日志) | 系统发生了什么? | 应用日志、Nginx 访问日志、错误堆栈 | ELK / Loki / Splunk | 文本型、海量、不可丢失 |
| Tracing(追踪) | 请求的完整路径? | 一次请求跨 N 个服务的耗时 | SkyWalking / Jaeger / Zipkin | 调用链、低采样率、关联 ID |
💡 原理:为什么是 3 个支柱而不是 1 个
- 只用 Metrics:知道 CPU 100%,但不知道哪个请求导致的
- 只用 Logging:知道应用报错了,但不知道全链路影响
- 只用 Tracing:能定位慢调用,但不知道整体服务健康度
三者互补,缺一不可。一个完整的可观测性体系必须同时回答 3 个问题:现在怎么样?发生了什么?为什么这样?
1.2 监控 vs 可观测性:本质区别
很多团队把"监控"和"可观测性"混为一谈,但两者的设计哲学截然不同:
| 维度 | 监控(Monitoring) | 可观测性(Observability) |
|---|---|---|
| 核心思想 | 已知问题 → 设告警 | 未知问题 → 能定位 |
| 数据来源 | 预设指标(CPU/内存/QPS) | 任意维度查询 |
| 告警方式 | 阈值告警 | 多维关联 + 根因分析 |
| 适用阶段 | 系统稳定期 | 复杂分布式 + 频繁迭代 |
| 代表工具 | Zabbix / Nagios | Prometheus / ELK / SkyWalking |
📌 实践:什么时候需要可观测性
- ✅ 微服务 > 10 个
- ✅ 每天发布 > 1 次
- ✅ SLO 要求 99.9%+
- ✅ 故障定位要求 < 10 分钟
- ❌ 单体应用、传统行业、月级发布
1.3 数据模型:4 大共性要求
不管 Metrics / Logging / Tracing 哪一类数据,生产级的可观测性体系都必须满足 4 个共性要求:
| 要求 | 说明 | Metrics | Logging | Tracing |
|---|---|---|---|---|
| 标签化 | 维度可切片 | Labels(service、region) | Log Labels | Span Tags |
| 关联性 | 一次请求能串起来 | TraceID 关联 | TraceID 字段 | TraceID 根 |
| 时序性 | 时间维度分析 | timestamp 必备 | @timestamp 必备 | 起始时间 |
| 低成本 | 数据可降采样 | Recording Rules | Log Levels | 采样率 |
TraceID 是 3 支柱统一的"钥匙"——通过它可以把一次请求的指标、日志、追踪串起来。
二、可观测性体系全景:从 CNCF 到 OpenTelemetry
可观测性领域有 2 个绕不开的标准:CNCF Landscape(生态图)和 OpenTelemetry(数据采集标准)。
2.1 CNCF 可观测性 Landscape
CNCF(Cloud Native Computing Foundation)的可观测性 Landscape 把工具分成 4 层:
| 层级 | 职责 | 代表工具 |
|---|---|---|
| 数据采集(Instrumentation) | 生成/收集数据 | OpenTelemetry Agent、Filebeat、Promtail |
| 数据传输(Transport) | 数据转发 | Kafka、Vector、Fluentd |
| 数据存储(Storage) | 持久化、查询 | Prometheus、Elasticsearch、Loki、ClickHouse |
| 数据展示(Visualization) | 大盘、告警、UI | Grafana、Kibana、SkyWalking UI |
🎯 避坑点:别陷入"工具竞赛"
我见过太多团队"为了用 XX 工具而用 XX 工具"。工具是为业务服务的:
- 3 个服务的团队:单机 ELK + Zabbix 够了
- 30 个服务的团队:Prometheus + Loki + SkyWalking
- 300 个服务的团队:自研 + 商业 SaaS(Datadog / New Relic)
不要照搬大厂方案——你的规模配不上那个复杂度。
2.2 OpenTelemetry:数据采集的事实标准
OpenTelemetry(OTel) 是 CNCF 旗下统一 Metrics / Logging / Tracing 数据模型的开源项目,由 OpenCensus + OpenTracing 合并而来。目标:用一套 SDK 采集三类数据。
OTel 的核心组件:
| 组件 | 职责 | 部署位置 |
|---|---|---|
| API | 定义数据模型和接口 | 应用依赖 |
| SDK | 数据采集和聚合实现 | 应用内嵌 |
| Collector | 数据接收、处理、转发 | 独立服务 / Sidecar |
| Instrumentation | 自动埋点库(HTTP / JDBC / Redis 等) | SDK 集成 |
💡 原理:OTel 怎么"统一"三支柱
- 统一上下文传播(Context Propagation):W3C TraceContext 标准,所有语言、所有工具一致
- 统一资源模型(Resource):Service、Instance、Namespace 等通用属性
- 统一协议(OTLP):基于 gRPC/HTTP 的数据传输
- 统一 SDK:一套 API 同时输出 Metrics/Logs/Traces
意义:换底层存储不影响应用代码——以前 Micrometer → Prometheus、Logback → Logstash 各一套埋点,现在统一成 OTel。
2.3 Spring Boot 应用集成 OTel
Spring Boot 3.x 已经内置 Micrometer Tracing(基于 OTel)——这是 Java 生态最方便的接入方式。
| |
| |
📌 实践:日志里必须有 TraceID
没有 TraceID 关联的日志,90% 的故障定位会失败。上例中
[order-service,abc123,def456]就是关键——任何一条 ERROR 日志都能反查完整调用链。没有这一行的日志系统 = 没有灵魂的日志系统。
三、Prometheus 深度:从指标模型到生产调优
Prometheus 是 CNCF 第二个毕业的项目(仅次于 Kubernetes),已经成为云原生时代 Metrics 的事实标准。
3.1 Prometheus 是什么
Prometheus 的核心特征:
| 特征 | 说明 |
|---|---|
| 拉模式(Pull) | Prometheus 主动拉取应用 /metrics 端点 |
| 多维数据模型 | 时间序列 + 标签(labels) |
| PromQL | 强大的查询语言 |
| 本地 TSDB | 自带存储(2 周保留) |
| 告警规则 | 内置告警 + Alertmanager |
| 云原生友好 | K8s ServiceMonitor / PodMonitor |
3.2 指标数据模型
每条时间序列 = 指标名 + 标签集 + 时间戳 + 样本值:
| |
| 字段 | 含义 | 示例 |
|---|---|---|
| 指标名 | 描述测量内容 | http_server_requests_seconds_count |
| 标签 | 维度 | {method, uri, status} |
| 时间戳 | 毫秒 | 1717900000 |
| 样本值 | float64 | 12345 |
指标类型(4 种):
| 类型 | 说明 | 例子 |
|---|---|---|
| Counter | 单调递增计数器 | 请求总数、错误数 |
| Gauge | 任意增减 | CPU 使用率、连接池大小 |
| Histogram | 分桶统计(可计算 P99) | 请求耗时分布 |
| Summary | 客户端聚合的分位数 | 客户端 P95 |
🎯 避坑点:标签基数(Cardinality)爆炸
每个唯一标签组合都是一条时间序列。常见坑:
- ❌
{user_id="123456"}→ 1 亿用户 = 1 亿条序列 → Prometheus 必崩- ❌
{email="user@example.com"}→ 同样是高基数- ✅
{method, uri, status, service}→ 低基数(几十种)铁律:标签总数 × 唯一值数 < 1000 万。否则上 Thanos / Cortex / Mimir。
3.3 PromQL 实战
PromQL(Prometheus Query Language) 是 Prometheus 的灵魂。
基础查询
| |
聚合查询
| |
关联查询
| |
💡 原理:为什么是 histogram_quantile 而不是 quantile
- quantile:在 Prometheus 端聚合(但先聚合再算分位数是错的)
- histogram_quantile:在客户端预分桶,按桶估算分位数
经典反例:用
quantile(0.99, rate(x[5m]))算 P99,得到的是全局聚合后的 P99,不是单实例的 P99。
3.4 relabel 与 metric_relabel:降本利器
Relabel 是 Prometheus 减少存储的关键机制。
| |
常见的 relabel 动作:
| action | 用途 | 示例 |
|---|---|---|
keep | 保留匹配 | 只保留 production namespace |
drop | 丢弃 | 丢弃高基数 label |
replace | 重命名/新增 | service 标签 |
labelmap | 批量重命名 | 把 __meta_* 转成 label |
hashmod | 分片 | 远端存储分片 |
3.5 存储与远程写入
Prometheus 本地 TSDB 适合 15 天以内。生产推荐 Prometheus + 远端存储:
| |
主流远端存储对比:
| 方案 | 特点 | 适合 |
|---|---|---|
| Thanos | 对象存储 + 全局视图 + 下采样 | 中小团队 + K8s |
| Cortex | 多租户 + 水平扩展 | 大型组织 |
| Mimir | Cortex 升级版(Grafana Labs) | 超大规模 |
| VictoriaMetrics | 单二进制、性能极致 | 资源敏感 |
| InfluxDB / TDengine | 通用时序库 | 已有栈复用 |
📌 实践:Prometheus 容量估算
单个 Prometheus 实例稳定支持 200 万活跃序列 + 10 万 samples/s 摄入。
容量公式:
1 2存储 GB = 活跃序列数 × 0.001 KB × 保留天数 = 2,000,000 × 0.001 × 15 = 30 GB超 200 万序列必须分片(Hash 分片) 或上远端存储。
3.6 告警规则
| |
🎯 避坑点:告警规则的"for"参数
for: 5m表示条件持续 5 分钟才触发。这是反"告警风暴"的第一道关:
- ❌ 立即触发:网络抖动 1 秒 = 全员被告警轰炸
- ✅ 持续 5 分钟:真正的故障才会触发
生产推荐 for ≥ 2 分钟,配合后续的告警分级。
3.7 Spring Boot 实战:自定义业务指标
用 Micrometer 把"业务动作"变成 Prometheus 指标——这是从"系统指标"迈向"业务指标"的关键一步。
| |
| |
PromQL 验证:
| |
📌 实践:业务指标的 4 大原则
- 命名规范:
{业务}_{动作}_{单位}(如order_create_total)- 标签低基数:维度种类 < 10(如
channel只有 app/web/mini 三种)- histogram 必开:
publishPercentileHistogram=true才能算 P99- 配套告警:每条业务指标必须有对应告警规则
生产经验:业务指标比系统指标贵 10 倍价值——CPU 100% 你不知道影响什么,但"下单成功率从 99.9% 跌到 95%“直接关系到 GMV。
四、Grafana 大盘设计:变量、模板、联动
Grafana 几乎是 Prometheus 时代可视化的事实标准。一个设计良好的 Grafana 大盘能 让 30 分钟的故障定位缩短到 3 分钟。
4.1 Grafana 核心概念
| 概念 | 说明 |
|---|---|
| Dashboard | 大盘(多 panel 组合) |
| Panel | 单个图(折线 / 表格 / 状态点) |
| Variables | 变量($service、$region) |
| Datasource | 数据源(Prometheus / ES / Loki) |
| Folder | 文件夹(业务/基础) |
| Alert | Grafana 也能直接配告警(推荐用 Alertmanager) |
4.2 大盘设计的 4 层架构
| 层级 | 用途 | 典型指标 | 谁看 |
|---|---|---|---|
| 全局总览 | 一眼看全公司状态 | 总 QPS、总错误率、关键 SLO | CTO / SRE 主管 |
| 应用总览 | 看单个业务线状态 | 服务 QPS、错误率、P99 | 应用 Owner |
| 深入诊断 | 看单个服务细节 | JVM、DB 连接池、下游依赖 | 业务研发 |
| 根因分析 | 定位具体问题 | 慢 SQL、慢调用、异常堆栈 | On-Call 工程师 |
4.3 必装的 Grafana 插件
| 插件 | 用途 |
|---|---|
| Pie Chart | 饼图(错误分布) |
| Bar Gauge | 进度条(资源使用率) |
| Geomap | 地图(多机房分布) |
| Stat | 单值大数字(KPI 看板) |
| State Timeline | 状态时间线(服务状态变化) |
| Node Graph | 节点图(服务依赖关系) |
4.4 大盘设计 Checklist
- 黄金指标 4 个:QPS、错误率、P99、饱和度
- USE 指标(资源):Utilization、Saturation、Errors
- RED 指标(服务):Rate、Errors、Duration
- 变量可筛选:service / region / env 可切换
- 链接可跳转:大盘之间能 drill-down
- 告警标注:触发告警的曲线变红
- 加载 < 3 秒:大盘查询不能太复杂
💡 原理:黄金信号 vs USE vs RED
方法 适用 来源 黄金信号(Google SRE) 服务 Latency、Traffic、Errors、Saturation USE 方法(Brendan Gregg) 资源 Utilization、Saturation、Errors RED 方法(Tom Wilkie) 服务 Rate、Errors、Duration 黄金信号是基础——任何服务都该有。USE 适合基础设施(CPU/内存/磁盘/网络),RED 适合微服务(QPS/错误率/响应时间)。
4.5 Grafana 统一告警入口
Grafana 8+ 支持 统一告警(Unified Alerting),可以同时接 Prometheus / Loki / ES 数据源:
| |
📌 实践:Grafana vs Alertmanager 告警怎么选
| 场景 | 推荐 | |—| | 简单的指标阈值 | Alertmanager(更稳定、生态好) | | 多数据源关联(Grafana Unified Alerting) | Grafana | | 复杂的 SLO / Burn Rate | Grafana(支持多窗口多燃烧率) | | 邮件 / 钉钉 / Slack 统一路由 | Alertmanager(功能更全) |
生产推荐两者并行——Alertmanager 管"已知阈值”,Grafana 管"高级 SLO"。
五、ELK 日志体系:Filebeat → Logstash → ES → Kibana
ELK(Elasticsearch + Logstash + Kibana) 是日志领域的"老牌劲旅",至今仍是合规日志、审计日志、长保留日志的首选。
5.1 ELK 体系架构
各组件职责:
| 组件 | 职责 | 资源占用 | 替代品 |
|---|---|---|---|
| Filebeat | 轻量采集、日志文件追踪 | CPU/内存极低 | Fluent Bit、Vector |
| Logstash | 复杂解析、过滤、转换 | 重(JVM) | Fluentd、Vector |
| Elasticsearch | 倒排索引、全文检索 | 很重 | OpenSearch、Solr |
| Kibana | 可视化、查询、告警 | 中等 | Grafana(ES 数据源) |
5.2 选型:ELK 还是 Loki
这是 2024 年后最常被问到的问题。
| 维度 | ELK | Loki |
|---|---|---|
| 索引方式 | 全文倒排索引 | 标签索引(无倒排) |
| 查询能力 | 强(任意关键字) | 弱(只查标签 + 流式 grep) |
| 存储成本 | 高(1TB 日志 ≈ 1.5TB 索引) | 低(压缩 + 标签) |
| 适合场景 | 复杂日志查询、审计、合规 | 已知服务 + 标签查询 |
| 扩展性 | 复杂(要调分片、副本) | 简单(对象存储) |
| 运维成本 | 高 | 低 |
| 告警能力 | 强(Watcher) | 强(通过 Grafana) |
📌 实践:怎么选
- 业务日志(已知服务、按 traceID/level 查)→ Loki(便宜、简单)
- 审计日志(合规、保留 1 年、按任意字段查)→ ELK(功能强)
- 混合架构(推荐):业务日志走 Loki,审计/合规走 ELK
不要全部上 ELK——ES 集群运维是大坑,10 个节点起步。
5.3 Filebeat 采集配置
| |
5.4 Logstash 解析管道
| |
🎯 避坑点:Logstash 性能
Logstash 是 JVM 应用 + Grok 解析——非常吃 CPU 和内存。
- 生产推荐用 Filebeat → Kafka → Logstash(多 worker)
- 不要直接 Filebeat → Logstash(高并发会拖垮 Logstash)
- 复杂解析可以用 Vector(Rust 写的,性能是 Logstash 的 10 倍)
5.5 ES 索引生命周期管理(ILM)
ES 最大的坑是"分片只增不减"。生产必须配 ILM:
| |
4 个阶段的目的:
| 阶段 | 时间 | 动作 | 成本 |
|---|---|---|---|
| hot | 0-3 天 | 频繁读写、性能优先 | 高 |
| warm | 3-7 天 | 压缩、合并分片 | 中 |
| cold | 7-30 天 | 冻结(不占 JVM heap) | 低 |
| delete | 30+ 天 | 删除 | 0 |
5.6 Kibana 实战
Kibana 必备 4 类视图:
- Discover:自由查询 + 字段过滤
- Visualize:可视化(柱状图、饼图、地图)
- Dashboard:组合可视化
- Watcher:日志告警(错误日志突增、关键词出现)
生产推荐:Kibana 用于 深度日志调查,Grafana 用于 业务监控大盘——两个工具互补。
六、SkyWalking 链路追踪:分布式调用的"透视眼"
SkyWalking 是 Apache 顶级项目,国内 Java 生态用得最多的 APM 工具(比 Jaeger 更适合生产)。
6.1 SkyWalking 是什么
SkyWalking 核心组件:
| 组件 | 职责 | 部署 |
|---|---|---|
| Agent | 字节码增强、自动埋点 | 应用 JVM 启动参数 |
| OAP Server | 数据接收、聚合、分析 | 独立服务(集群化) |
| Storage | 持久化(ES/H2/MySQL/TiDB) | 后端存储 |
| UI | 调用链、拓扑图、告警 | Web |
6.2 Trace 数据模型
Trace = 一次完整请求的调用链,由 Span 组成:
Span 关键字段:
| 字段 | 含义 |
|---|---|
| traceId | 一次请求的全局 ID(关联指标/日志) |
| spanId | 当前 span 的 ID |
| parentSpanId | 父 span ID |
| operationName | 操作名(如 HTTP POST /api/order) |
| startTime / endTime | 起止时间 |
| duration | 耗时(毫秒) |
| tags | 标签(如 http.status_code=200) |
| logs | 关联日志事件 |
6.3 Java Agent 接入
最简单的方式——不改一行代码:
| |
K8s 部署(推荐用 initContainer 共享 agent):
| |
6.4 采样策略
全量追踪存储成本爆炸——必须采样:
| 策略 | 描述 | 适合 |
|---|---|---|
| 全采样 | 100% 追踪 | 开发/测试 |
| 按比例采样 | 1% / 10% 采样 | 生产(默认) |
| 按错误采样 | 正常请求 1%,错误 100% | 错误排查 |
| 按慢调用采样 | > 1s 全采 | 性能分析 |
| 按优先级采样 | 自定义规则 | 精细化运营 |
| |
🎯 避坑点:低采样率的"看不见的故障"
生产事故中 99% 的故障都在低采样率里被遗漏。经验:
- 错误请求、慢请求(> 1s)100% 采集
- 正常请求按业务量采样(0.1% ~ 10%)
- 关键服务(支付/订单)保持高采样
SkyWalking 支持通过 agent.force_sample_error_trace=true 强制错误全采。
6.5 SkyWalking 告警
| |
📌 实践:告警的去重和升级
SkyWalking 告警默认所有 OAP 节点都会发,集群部署要配
alarm.default-dingtalk-talk防重复。生产推荐 SkyWalking 告警 → Alertmanager → 统一路由(详见第九章)。
6.6 SkyWalking 实战:告警合并 + 采样调优
SkyWalking 集群部署(生产必备,3 节点起步):
| |
告警合并的 3 个核心配置:
| |
| 配置项 | 含义 | 推荐值 |
|---|---|---|
period | 检查周期 | 10s(关键)/ 60s(一般) |
silence-period | 告警静默期 | 5min(避免风暴) |
tags | 告警标签 | level: WARNING/CRITICAL |
message | 告警内容 | 含服务名+具体数值+Runbook 链接 |
采样调优实战:
| 业务类型 | 服务示例 | 推荐采样率 |
|---|---|---|
| 核心交易 | 支付、订单 | 100%(全采) |
| 重要业务 | 用户、商品 | 10% |
| 普通业务 | 评论、收藏 | 1% |
| 后台任务 | 报表、清理 | 0.1%(不开 trace) |
| 错误请求 | 所有错误 | 100%(强制采) |
| |
🎯 避坑点:采样率不均的"采样偏差"
错误教训:某团队对所有服务设 1% 采样,结果大促时一个 P0 故障在 1% 采样下只能看到 10 个 trace,完全无法定位根因。
对策:
- 关键服务保持 100% 采样(即使多花存储也值)
- 错误 + 慢调用强制 100% 采样
- 抽样不应该是均匀的——应该按业务重要性分层
生产经验:SkyWalking 集群 OAP 节点数 = (日均 span 数 ÷ 1000 万) 向上取整。100 万 span/天 = 1 节点,1000 万 span/天 = 2-3 节点。
七、Loki 轻量日志:LogQL 与标签设计
Loki 是 Grafana Labs 推出的"Prometheus 风格"日志系统,核心理念:只索引标签,不索引内容——成本比 ELK 低 10 倍。
7.1 Loki 架构
核心组件:
| 组件 | 职责 | 替代品 |
|---|---|---|
| Promtail | 日志采集(Filebeat-like) | Fluent Bit、Vector |
| Distributor | 接收、验证、分片 | - |
| Ingester | 写入 chunk、压缩 | - |
| Querier | 查询 | - |
| Query Frontend | 调度、缓存 | - |
| Storage | 对象存储 | S3 / OSS / MinIO / GCS |
7.2 标签设计:Loki 的命脉
Loki 的查询 = 标签过滤 + 文本流式 grep。标签设计直接决定查询性能。
| |
标签设计的 4 大原则:
| 原则 | 说明 | 反例 |
|---|---|---|
| 低基数 | 标签值种类 < 100 | ❌ user_id、order_id |
| 可枚举 | 已知的所有值 | ❌ email、phone |
| 查询频率高 | 经常用的过滤条件 | ❌ http_url(每个 URL 一条) |
| 业务维度 | 服务/环境/区域 | ❌ 时间戳(已是索引) |
生产推荐标签:
| |
🛑 误区警示:标签和消息内容的边界
- 标签:索引的、可枚举的、低基数的(结构化)
- 消息内容:不索引、文本流式扫描(自由文本)
❌ 把
user_id=12345做成标签 → 1 亿个时间序列 → Loki 必崩✅ 把
user_id=12345放消息内容 → 用{app="order"} |= "user_id=12345"查
7.3 LogQL 查询
LogQL = Loki 的查询语言,分两类:
Log 查询(流式)
| |
Metric 查询(聚合)
| |
7.4 Loki vs ELK 选型决策
💡 原理:Loki 为什么便宜
- ES:每条日志都建倒排索引 → 1TB 日志 → 1.5TB 索引 → 内存/磁盘成本高
- Loki:只索引标签(不到 1% 体积)+ 把日志流式压缩存到对象存储 → 1TB 日志 → 1.2TB 存储 → 成本低 5-10 倍
代价:Loki 全文搜索是流式 grep(扫整个 chunk),不查索引 → 慢 10-100 倍。
结论:知道"在哪查"(按服务/级别)用 Loki;想"全文搜任意关键字"用 ELK。
八、自动采集:让埋点"零感知"
可观测性体系最大的成本不是存储,是"埋点"。自动采集是工业级可观测性的核心。
8.1 三大采集模式
| 模式 | 描述 | 代表 | 适合 |
|---|---|---|---|
| Agent 注入 | 字节码增强,应用启动时挂载 | SkyWalking Agent、OTel Java Agent | Java 应用 |
| Sidecar | 应用旁路采集,每个 Pod 一个 | Filebeat Sidecar、Vector | 多语言 |
| DaemonSet | 节点级采集,Pod 共享 | Filebeat DS、Promtail DS、Node Exporter | K8s + 日志 |
8.2 Java Agent 自动埋点原理
SkyWalking / OTel Agent 都基于字节码增强(ByteBuddy / ASM)——不改业务代码,自动给所有方法加埋点。
SkyWalking 自动埋点支持的主流库(开箱即用):
| 类别 | 支持的库 |
|---|---|
| Web 框架 | Spring MVC / Spring WebFlux / Dubbo / gRPC / Struts |
| HTTP 客户端 | HttpClient / OkHttp / RestTemplate / Feign |
| 数据库 | MySQL JDBC / PostgreSQL JDBC / Druid / HikariCP |
| 缓存 | Jedis / Lettuce / Redisson |
| MQ | Kafka / RabbitMQ / RocketMQ / ActiveMQ |
| RPC | Dubbo / gRPC / Motan / SofaRPC |
📌 实践:Agent 接入 Checklist
- 业务包名过滤:
agent.service_name用appname-${env}模板- 慢 SQL 阈值:
agent.middleware.jdbc.slow_sql_threshold=500ms- 采样率:生产设 0.1(10%),关键服务 100%
- 日志关联:
%X{traceId}必须进日志格式- 优雅关闭:避免丢失最后 5s 的 span(
agent.force_reconnection_period)
8.3 K8s 自动采集拓扑
生产推荐混合模式:
- 应用层指标(JVM、HTTP、DB):Agent 注入(最准)
- 应用日志:Sidecar 或 stdout + DaemonSet(最稳)
- 主机指标(CPU/内存/磁盘/网络):node_exporter DaemonSet(最全)
- K8s 指标:kube-state-metrics + cAdvisor(必备)
8.4 自动采集清单
| 采集项 | 工具 | 模式 | 必装? |
|---|---|---|---|
| JVM 指标 | SkyWalking/OTel Agent | Agent | ✅ |
| HTTP 请求 | SkyWalking/OTel Agent | Agent | ✅ |
| 数据库调用 | SkyWalking/OTel Agent | Agent | ✅ |
| Redis 调用 | SkyWalking/OTel Agent | Agent | ✅ |
| MQ 消费 | SkyWalking/OTel Agent | Agent | ✅ |
| 应用日志 | Promtail / Filebeat | DS/Sidecar | ✅ |
| Nginx 日志 | Filebeat | DS | 视情况 |
| 主机指标 | node_exporter | DS | ✅ |
| K8s 指标 | kube-state-metrics | Deployment | ✅ |
| 容器指标 | cAdvisor | 内置 | ✅ |
| 数据库指标 | mysqld_exporter / postgres_exporter | Deployment | ✅ |
| Redis 指标 | redis_exporter | Deployment | 视情况 |
| Kafka 指标 | kafka_exporter | Deployment | 视情况 |
| LB 指标 | nginx-prometheus-exporter | DS | 视情况 |
🎯 避坑点:DaemonSet 数量 = 节点数
每个节点一个 Pod,别忘了:
- 资源限制(防止 Pod 抢资源)
- 节点亲和性(避免 Master 节点跑)
- 日志轮转(采集器本身会写日志,别把磁盘撑爆)
8.5 OpenTelemetry Operator:K8s 原生采集
OTel Operator 是 K8s 部署 OTel 的最佳实践。
| |
| |
📌 实践:OTel Operator 的优势
- 一行 annotation 注入 Agent,不需改 Deployment 模板
- 统一管理所有服务的 Agent 版本
- 自动注入 JAVA_TOOL_OPTIONS 环境变量
强烈推荐 K8s 环境用 OTel Operator——把"埋点"变成"声明式"。
8.6 实战:kube-prometheus-stack 一键部署完整监控
kube-prometheus-stack 是 CNCF 推荐的生产级监控方案,一行 Helm 命令部署完整套件。
| |
部署后包含的组件:
| 组件 | 数量 | 作用 |
|---|---|---|
| Prometheus Operator | 1 | 管理 Prometheus 生命周期 |
| Prometheus | 1 | 主指标采集(可副本) |
| Alertmanager | 1 | 告警路由 |
| Grafana | 1 | 可视化 |
| node-exporter | DaemonSet | 主机指标 |
| kube-state-metrics | 1 | K8s 资源指标 |
| pushgateway | 1 | 短任务指标 |
| 预设告警规则 | 200+ | K8s 告警全开箱即用 |
Kube-prometheus-stack 的 ServiceMonitor 模式(自动发现 + 抓取):
| |
PrometheusRule 模式(告警规则即代码):
| |
📌 实践:kube-prometheus-stack 调优清单
- 存储:Prometheus 100Gi 起步(按 30 天保留 × 100 万序列估算)
- 副本:Prometheus 用 2 副本 + AntiAffinity(避免单点)
- 远程存储:接 Thanos/Mimir 长期保留
- 抓取间隔:核心服务 15s,普通服务 30s,批处理 60s
- 告警去重:Alertmanager + AlertmanagerConfig CRD
- Grafana 持久化:配置用 ConfigMap 挂载(避免重启丢配置)
- NodePort/Ingress:通过 Ingress 暴露 Grafana(生产不要 NodePort)
升级路径(按规模演进):
生产经验:30+ 服务的团队直接上 kube-prometheus-stack 即可——所有 K8s 告警规则都开箱即用,比自研省 3 个月工作量。
九、自动告警:从阈值到 On-Call
告警的本质是"在故障变严重之前通知能处理它的人"。一个好的告警系统需要解决 4 个问题:触发什么、什么时候触发、通知谁、怎么升级。
9.1 告警的 4 大属性
| 属性 | 含义 | 例子 |
|---|---|---|
| 触发规则(What) | 什么条件下触发 | P99 > 1s 持续 5min |
| 持续时间(When) | 持续多久才发 | for: 5m |
| 通知对象(Who) | 通知谁 | On-Call 工程师 |
| 升级路径(Escalation) | 没人响应怎么办 | 5min 升级到主管 |
9.2 告警分级:P0/P1/P2/P3
生产推荐 4 级告警:
| 等级 | 触发条件 | 响应时间 | 通知方式 | 升级路径 |
|---|---|---|---|---|
| P0 紧急 | 核心业务不可用 | 5 分钟 | 电话 + 短信 + 钉钉 | 5min → 主管,15min → 总监 |
| P1 严重 | 部分用户受影响 | 30 分钟 | 钉钉 @all | 30min → 主管,1h → 总监 |
| P2 警告 | 接近阈值 | 4 小时 | 钉钉 @值班 | 1h → 主管 |
| P3 信息 | 仅记录 | 24 小时 | 邮件 / 群消息 | 不升级 |
🛑 误区警示:把所有告警都标 P0
P0 泛滥 = 没有 P0。我见过某团队 73 条告警全标 P0,结果:
- 真出 P0 时,没人当真
- 工程师把钉钉群设成免打扰
- 告警系统变成"狼来了"
核心原则:P0 每周最多触发 1-2 次,否则就不是 P0。
9.3 Alertmanager 路由配置
| |
9.4 告警通知通道
| 通道 | 适用 | 优势 | 劣势 |
|---|---|---|---|
| 钉钉 / 飞书 / 企微 | 国内主流 | 集成好、免费 | 易刷屏 |
| PagerDuty | 国际化 | 专业 On-Call | 付费 |
| OpsGenie | 国际化 | 通知升级完善 | 付费 |
| 电话 / 短信 | P0 紧急 | 必达 | 贵、骚扰 |
| 邮件 | P3 留档 | 不骚扰 | 慢 |
生产推荐组合:
- P0:钉钉 + 电话(双通道) + 自动语音呼叫
- P1:钉钉 @值班
- P2:钉钉群消息
- P3:邮件 + 群消息
9.5 告警值班(On-Call)轮值
没有 On-Call 轮值 = 告警来了没人处理。
| 角色 | 职责 | 比例 |
|---|---|---|
| Primary | 第一响应人 | 1 人 |
| Secondary | Primary 不响应时接手 | 1 人 |
| Manager | 重大故障协调 | 1 人 |
轮值周期:
| 业务规模 | 轮值周期 | 备注 |
|---|---|---|
| 小型(1-5 服务) | 1 周 | 工程师轮值 |
| 中型(10-50 服务) | 1 周 | SRE 团队轮值 |
| 大型(100+ 服务) | 1 天 | 7×24 专业 SRE |
📌 实践:On-Call 必做 3 件事
- 轮值表提前发布——所有人都知道自己什么时候 On-Call
- 值班手机必带——On-Call 时间段手机不离身
- On-Call 补偿——调休 / 加班费 / On-Call 津贴
On-Call 是反人性的,不补偿会引发团队离职。
十、告警治理:告警疲劳、降噪、Runbook
没有治理的告警系统 = 没有告警。告警治理的目标是:每条告警都被响应。
10.1 告警疲劳:最常见的 3 大症状
| 症状 | 表现 | 后果 |
|---|---|---|
| 告警泛滥 | 每天 100+ 告警 | 工程师设免打扰 |
| 重复告警 | 同一故障 50 条 | 真正重要的被淹没 |
| 假阳性多 | 触发 10 次只 1 次真 | 没人当真 |
10.2 告警降噪的 5 大技术
1. 告警分组(Grouping)
| |
2. 告警抑制(Inhibition)
| |
3. 告警静默(Silences)
| |
4. 告警去重
| |
5. 告警路由(智能升级)
| |
10.3 SLO 驱动的告警(多窗口多燃烧率)
传统阈值告警(P99 > 1s)的问题是:阈值是拍脑袋的。SLO 告警用"剩余预算"判断。
| SLO 概念 | 说明 |
|---|---|
| SLO | 服务质量目标(如可用性 99.9%) |
| Error Budget | 错误预算(30 天内允许 0.1% × 30 × 86400 = 2484s 不可用) |
| Burn Rate | 错误预算消耗速度(1x = 30 天刚好耗完,2x = 15 天耗完) |
Google SRE 推荐的 4 个告警窗口:
| |
🎯 避坑点:SLO 告警 vs 阈值告警
- 阈值告警:P99 > 1s 持续 5min → 触发。简单但不准
- SLO 告警:错误预算 1h 燃烧 10% → 触发。科学但复杂
生产推荐:核心业务用 SLO 告警(细),普通业务用阈值告警(粗)。
10.4 Runbook:让告警"自带解法"
Runbook 是告警的最佳拍档——告诉响应人"我看到这条告警,应该做什么"。
| |
💡 原理:Runbook 的反"告警疲劳"作用
- 降低 MTTR(平均恢复时间)——新人也能 5 分钟内处理
- 降低 MTTA(平均确认时间)——响应人知道严重程度
- 减少误操作——明确"该做什么"和"不该做什么"
生产强制要求:P0/P1 告警必须有 Runbook。
10.5 告警治理 Checklist
- 告警分级——P0/P1/P2/P3 全员对齐
- 抑制规则——避免风暴
- On-Call 轮值——7×24 覆盖
- Runbook 完备——P0/P1 100% 覆盖
- 告警复盘——每月一次,清理假阳
- 告警健康度——告警数 / 服务数 < 1(健康)
- 值班补偿——调休或加班费
- 升级路径明确——30min 没人响应自动升级
十一、真实案例
11.1 某电商大促:从 7 套监控系统到统一可观测性
背景:2021 年双 11 大促,技术栈 200+ Spring Cloud 微服务 + 30+ 中间件 + 4 个数据中心。
重构前的 5 大痛点:
- 数据孤岛:Zabbix 看不到 JVM 详细指标,Prometheus 看不到数据库慢查询,商业 APM 看不到业务指标
- 告警混乱:73 条告警全标 P0,真出 P0 时没人当真
- 定位缓慢:故障平均定位 30 分钟(大促峰值 1 小时+)
- 存储爆炸:日志日均 5TB,ES 集群 50+ 节点
- On-Call 痛苦:工程师每周值班 2 次,每次 12 小时,离职率激增
重构方案(历时 3 个月,“1+1+1+1+N”):
第一步:指标统一(4 周)
- 全量接入 Prometheus + SkyWalking Agent
- 200+ 服务全埋点,业务指标优先(下单成功率、支付成功率、库存命中率)
- Thanos 做远端存储,保留 1 年
- Grafana 4 层大盘(总览 / 应用 / 诊断 / 根因)
第二步:日志统一(3 周)
- 业务日志(80%):Loki + Promtail + 对象存储
- 审计日志(20%):ELK 集群(缩到 10 节点)
- 日志格式统一:
%X{traceId}必须输出 - 7 套日志平台下线 5 套
第三步:链路统一(2 周)
- SkyWalking 全量接入
- 关键服务(支付/订单)100% 采样
- 错误和慢调用强制 100% 采样
- Jaeger、自研链路追踪全部下线
第四步:告警统一(2 周)
- Alertmanager 统一告警路由
- 4 级告警(P0/P1/P2/P3)+ On-Call 轮值
- 抑制规则 + Runbook 100% 覆盖 P0/P1
- 5 套通知通道收敛成 2 套(钉钉 + 电话)
重构后的收益(2022-2025):
| 指标 | 重构前 | 重构后 | 提升 |
|---|---|---|---|
| 告警数 | 日均 800+ | 日均 50 | 降 16 倍 |
| MTTA(平均确认) | 15 分钟 | 1 分钟 | 降 15 倍 |
| MTTR(平均恢复) | 45 分钟 | 8 分钟 | 降 5.6 倍 |
| ES 节点数 | 50+ | 15 | 降 70% |
| 存储成本 | 50 万/月 | 18 万/月 | 降 64% |
| On-Call 满意度 | 2.1/5 | 4.3/5 | 升 2 倍 |
关键教训:
- 不要为了"全栈可观测性"硬上 Datadog——贵且黑盒,自建 + 开源是性价比最高的路径
- 告警治理比建设更难——花 50% 时间在告警分级 + Runbook
- On-Call 补偿是底线——没有补偿的可观测性就是压榨
- 业务指标比系统指标贵 10 倍价值——CPU 100% 你不知道影响什么,“支付成功率从 99.9% 跌到 95%“直接关系到 GMV
- 可观测性是持续工程——不是"建设完就完了”,每月告警健康度复盘、季度容量评估、年度架构 review
痛点:
- 7 套监控(Zabbix + Prometheus + 商业 APM + 自研 + …)
- 5 套告警通道(钉钉/飞书/Slack/邮件/电话)
- 3 套日志平台(ELK × 2 + 商业日志)
- 2 套链路追踪(自研 + SkyWalking)
- 故障定位 30+ 分钟,告警风暴频繁
方案(“1+1+1+1+N”):
收益:
- 告警数从日均 800+ 降到 50(降 16 倍)
- 故障定位从 30 分钟降到 3 分钟
- MTTR 从 45 分钟降到 8 分钟
- 存储成本降 40%(Loki 替代部分 ES)
11.2 某金融:合规 + 全链路追踪
背景:传统金融机构,监管要求审计日志保留 5 年。
痛点:
- ELK 容量爆炸(每天 2TB 日志)
- ES 集群 50+ 节点
- 监管检查要求"任意交易 5 分钟内可追溯”
方案:
核心设计:
- 三层存储:Hot (ES 7天) → Warm (OSS 90天) → Cold (蓝光 5年)
- TraceID 全链路贯穿:业务日志 + 审计日志 + 链路追踪强关联
- 告警与监管联动:核心交易异常 → 监管报送接口
收益:
- ES 节点从 50+ 减到 15(降 70%)
- 5 年内任意交易 5 分钟可查
- 通过等保三级 + 银保监现场检查
11.3 某 SaaS:Loki 替代 ELK 的成本优化
背景:SaaS 产品,30+ 服务,日志量 500GB/天。
痛点:
- ES 集群 20 节点,月成本 8 万
- 查询性能差,复杂查询 30 秒
- 业务查询多是"按服务/级别"(80% 场景),全文搜是少数
方案:
- 业务日志(80% 流量)→ Loki + Promtail + Grafana
- 审计日志(20% 流量,按全文字段)→ 保留 ELK 小集群(5 节点)
收益:
- 存储成本从 8 万/月 → 1.5 万/月(降 80%)
- 按服务/级别查询速度提升 5 倍
- ES 集群维护成本几乎归零
教训:
- 不要照搬"大厂都用 ELK"——Loki 在"已知服务"场景下更合适
- 80/20 原则:80% 的查询是"已知维度"(服务/级别/时间),只有 20% 是全文搜
十二、总结
12.1 可观测性体系的 3 大核心要素
- 三支柱统一:Metrics + Logging + Tracing 用 TraceID 关联
- 自动采集:Agent / Sidecar / DaemonSet,埋点零感知
- 分级告警:P0/P1/P2/P3 + On-Call + Runbook
12.2 选型速查
| 场景 | 推荐 |
|---|---|
| 业务日志(按服务查) | Loki |
| 审计日志(合规、全文) | ELK |
| 链路追踪(Java 为主) | SkyWalking |
| 指标监控 | Prometheus + Grafana |
| 自动埋点 | OTel Agent / SkyWalking Agent |
| 告警路由 | Alertmanager |
| K8s 部署 | OTel Operator + DaemonSet |
12.3 何时不该上复杂体系
| 业务特征 | 推荐方案 |
|---|---|
| 微服务 < 5 个 | Zabbix + 单机 ELK + 商业 APM |
| 微服务 5-30 | Prometheus + Grafana + Loki |
| 微服务 30-100 | + SkyWalking + 远端存储 |
| 微服务 100+ | + 商业 SaaS(Datadog / NewRelic) |
12.4 系列预告
这是 Java Web 微服务系列 的第 9 篇。后续计划:
- 可观测性实战:从零搭建生产级监控体系
- Spring Cloud Alibaba 实战:Nacos + Sentinel + Seata + SkyWalking 全套
- 异地多活:单元化、流量调度、灰度发布、可观测性联动
- 生产事故复盘:从 30+ 真实事故看可观测性价值
- AI 运维(AIOps):异常检测、容量预测、根因分析
十三、监控与日志实施 Checklist
13.1 采集层 Checklist
- JVM 指标:所有 Java 服务挂载 Agent
- HTTP 指标:QPS / P99 / 错误率全覆盖
- DB 指标:mysqld_exporter / postgres_exporter
- 中间件指标:Redis / Kafka / RabbitMQ Exporter
- 主机指标:node_exporter DaemonSet
- K8s 指标:kube-state-metrics + cAdvisor
- 应用日志:Promtail / Filebeat 采集 + 关联 TraceID
- 链路追踪:SkyWalking / OTel Agent 注入
13.2 存储层 Checklist
- 指标存储:Prometheus + 远端存储(Thanos/Mimir)
- 日志存储:业务用 Loki,审计用 ELK
- 链路存储:SkyWalking + ES 后端
- 生命周期管理:指标 15 天、日志 30 天、链路 7 天
- 容量规划:存储 GB = 速率 × 86400 × 保留天数 × 1.5
13.3 可视化层 Checklist
- 4 层大盘:总览 / 应用 / 诊断 / 根因
- 黄金信号:QPS / 错误率 / P99 / 饱和度
- USE / RED 指标:资源 + 服务双视角
- 变量可筛选:service / region / env
- 告警标注:触发告警的曲线变红
- 加载 < 3 秒:避免复杂查询
13.4 告警层 Checklist
- 4 级告警:P0/P1/P2/P3
- On-Call 轮值:7×24 覆盖
- 抑制规则:避免告警风暴
- Runbook 完备:P0/P1 100% 覆盖
- SLO 告警:核心业务用 Burn Rate
- 值班补偿:调休 / 加班费
- 升级路径:30min 没人响应自动升级
13.5 团队层 Checklist
- SRE 能力:能调优 Prometheus + 写 PromQL
- 研发能力:会看 SkyWalking 慢调用 + 优化 SQL
- 值班制度:7×24 响应
- 复盘机制:P0/P1 24h 内复盘 + RCA
- 告警健康度:告警数 / 服务数 < 1
十四、常见问题 FAQ
Q1:SkyWalking vs Jaeger 怎么选?
A:Java 生态选 SkyWalking。
| 维度 | SkyWalking | Jaeger |
|---|---|---|
| 自动埋点 | 强(20+ 主流库) | 弱(要手写 SDK) |
| JVM 指标 | 内置 | 需另接 |
| 服务拓扑 | 自动绘制 | 需另接 |
| 告警 | 内置 | 需另接 |
| 适合 | Java 微服务首选 | 多语言、Go/Python |
Q2:Prometheus 标签基数爆炸怎么办?
A:3 个步骤:
- 找:用
tsdb工具查 top 高基数标签 - 砍:relabel_configs 删除不必要标签
- 分:超 200 万序列上 Thanos / Mimir 分片
| |
Q3:Loki 全文搜索很慢怎么办?
A:Loki 不适合全文搜索。混合架构:
- 80% 查询(按服务/级别)→ Loki
- 20% 查询(任意关键字)→ ELK
如果一定要 Loki 全文搜:升级 SSD + 加 CPU + 调高 query_timeout。
Q4:Java Agent 影响性能吗?
A:影响 < 5%(生产实测)。
| 场景 | 性能损耗 |
|---|---|
| 正常调用 | < 3% |
| 高 QPS 服务(10万 QPS) | < 5% |
| FullGC 频繁时 | < 8% |
如果不能接受:用 Sidecar + eBPF(Cilium Tetragon)—— 0 侵入但成熟度不够。
Q5:ES 集群扩容难怎么办?
A:改用 ILM + 冷热分层。
- Hot 节点:SSD,3 副本
- Warm 节点:HDD,1 副本 + 压缩
- Cold 节点:OSS + 冻结索引
扩容时加 Warm/Cold 节点比加 Hot 节点便宜 10 倍。
Q6:告警风暴怎么处理?
A:4 步止血:
- 立即分组抑制:
inhibit_rules配 critical 抑制 warning - 临时静默:
amtool silence add静默 1 小时 - 修复根源:等系统恢复后逐步放开
- 复盘清理:找出根因(一般是部署/网络故障),加 SLO 兜底
Q7:K8s 集群上怎么部署整套监控?
A:kube-prometheus-stack 一键部署(生产推荐)。
| |
包含:
- Prometheus Operator
- Alertmanager
- Grafana
- node_exporter
- kube-state-metrics
- 一堆预设告警规则
Q8:可观测性建设顺序是什么?
A:4 阶段:
| 阶段 | 周期 | 内容 |
|---|---|---|
| 1. 基础 | 1-2 月 | Prometheus + Grafana + Agent 埋点 |
| 2. 日志 | 1 月 | Loki/ELK + 日志关联 TraceID |
| 3. 链路 | 1 月 | SkyWalking + 慢调用分析 |
| 4. 治理 | 持续 | 告警分级 + On-Call + Runbook |
别想一步到位——先把基础打好,用 3 个月走完前 3 阶段,第 4 阶段持续优化。
Q9:自研 APM 还是用开源?
A:直接用开源。
- 30+ 服务:SkyWalking 够用
- 100+ 服务:商业 SaaS(Datadog / NewRelic)比自研便宜
- 只有 1-2 服务:自研 ROI 太低
自研 APM 的坑:
- 字节码增强框架(ByteBuddy / ASM)有兼容性问题
- 采样策略调不好会丢关键 trace
- 自研 UI 永远不如 Grafana
Q10:告警的"沉默"该怎么设计?
A:3 类沉默合理:
- 计划内维护:部署/升级期间,静默相关服务告警
- 依赖告警:下游服务告警时,抑制上游(避免重复)
- 静默期后强制确认:
amtool silence expire24h 强制检查
永远不要:
- 静默告警 7 天以上
- 静默 P0/P1 告警超过 30 分钟
Q11:Prometheus 集群怎么分片?
A:Hash 分片 + Sidecar 模式。
| |
分片策略选择:
| 策略 | 优点 | 缺点 | 适合 |
|---|---|---|---|
| 按 service hash | 数据均匀 | 跨 service 查询需要 fanout | 中小规模 |
| 按 namespace | 团队边界清晰 | 单 namespace 太大时不均 | 多团队 |
| 按 region | 跨地域隔离 | 全局查询难 | 多 region |
| Sidecar(每节点一个) | 节点级数据隔离 | 元数据查询复杂 | 大型集群 |
经验公式:
- 每分片活跃序列 < 200 万
- 每分片摄入速率 < 10 万 samples/s
- 总活跃序列 = 分片数 × 200 万
Q12:链路追踪怎么和日志关联?
A:TraceID 是桥梁。3 步实现:
- Agent 自动注入:SkyWalking/OTel 自动把 traceId 放进 MDC
- 日志格式输出 traceId:
%X{traceId}(Logback/Log4j2) - 存储端建索引:ES/Loki 把 traceId 设为可查询字段
| |
查询流程:
- 用户报障:“我刚才下单失败”
- SRE 拿到用户 traceId(如
abc123) - ELK 查询:
traceId:abc123→ 拿到完整业务日志 - SkyWalking 查询:同一 traceId → 拿到完整调用链耗时
- 10 分钟内定位根因
📌 实践:没有 TraceID 关联 = 监控失明
我见过多个团队建设了 Prometheus + ELK + SkyWalking 但没有关联,结果:
- 知道 CPU 100%(Prometheus)
- 知道应用报错(ELK)
- 知道调用慢(SkyWalking)
- 但三套数据连不起来,故障定位依然慢
铁律:任何日志、任何 trace、任何 metric,必须能用 TraceID 关联。
Q13:可观测性数据保留多久合适?
A:分级保留——成本和价值的平衡。
| 数据类型 | 热存储(快速查询) | 冷存储(合规/取证) | 永久 |
|---|---|---|---|
| 指标(Metrics) | 15-30 天 | 1 年(远端存储) | - |
| 业务日志 | 7-15 天 | 90 天 | - |
| 审计日志 | 30 天 | - | 5 年+(合规) |
| 链路追踪 | 3-7 天 | - | - |
| 告警历史 | 90 天 | 1 年 | - |
成本估算(以 100 服务、日均 500GB 数据为例):
| |
降本 3 招:
- 采样:trace 采样 10%(降 90% 成本)
- 冷热分层:30 天前日志扔到 OSS/蓝光(降 80% 成本)
- 字段裁剪:日志只保留必要字段(降 50% 体积)
Q14:如何评估可观测性体系是否成熟?
A:4 个等级。
| 等级 | 特征 | 关键指标 | 团队状态 |
|---|---|---|---|
| L1 救火 | 出事现抓 | MTTR > 1h | 1-2 个工程师手动查 |
| L2 监控 | 有大盘 + 告警 | MTTR 30min | 团队 SRE 兼职 |
| L3 可观测 | 3 支柱齐全 + 关联 | MTTR 5-10min | 7×24 On-Call |
| L4 自愈 | AIOps 异常检测 + 自愈 | MTTR < 5min | AIOps 平台 + SRE |
自评 Checklist:
- 故障定位 < 10 分钟(MTTR)
- 告警准确率 > 80%(假阳 < 20%)
- 日志有 traceId 关联
- 3 支柱数据都覆盖
- 7×24 On-Call
- 90% 告警有 Runbook
- 月度告警健康度复盘
生产目标:从 L1 到 L3,6-12 个月;从 L3 到 L4,12-24 个月。
Q15:AI 运维(AIOps)怎么落地?
A:3 阶段渐进。
| 阶段 | 能力 | 工具 |
|---|---|---|
| 阶段 1:异常检测 | 指标自动告警(替代阈值) | Prometheus 智能告警 / Grafana ML |
| 阶段 2:根因分析 | 自动定位故障域 | SkyWalking + 知识图谱 / 阿里鹰眼 |
| 阶段 3:自动修复 | 故障自愈(限流/降级/扩容) | Sentinel + K8s Operator + ChatOps |
生产经验:
- 阶段 1 容易(已有开源方案)
- 阶段 2 难(需要知识图谱 + 历史故障库)
- 阶段 3 慎用(误操作风险大,先 P3 故障试水)
核心原则:AIOps 永远是人 + AI 协作,不是 AI 替代人。AI 给"建议",人做"决策"。
推荐阅读
官方文档:
- Prometheus 官方文档:https://prometheus.io/docs/
- Grafana 官方文档:https://grafana.com/docs/
- OpenTelemetry 官方文档:https://opentelemetry.io/docs/
- SkyWalking 官方文档:https://skywalking.apache.org/docs/
- Loki 官方文档:https://grafana.com/oss/loki/
- Elastic Stack 官方文档:https://www.elastic.co/guide/
书籍:
- 《Site Reliability Engineering》(Google)—— SRE 圣经
- 《Observability Engineering》(O’Reilly)—— 可观测性权威指南
- 《Distributed Systems Observability》(Cindy Sridharan)—— 分布式系统可观测性
- 《Prometheus: Up & Running》(Brian Brazil)—— Prometheus 实战
- 《Cloud Native Observability》(Shiwan Kohli)—— 云原生可观测性
技术博客:
- Grafana 官方博客:Loki、Tempo、Mimir 新特性
- CNCF Observability TAG:可观测性技术趋势
- OpenTelemetry Blog:采集标准演进
- 字节跳动技术博客:可观测性实践
- 美团技术团队:监控告警体系
- 阿里云原生:可观测性产品化
开源项目:
- Prometheus:https://github.com/prometheus/prometheus
- Grafana:https://github.com/grafana/grafana
- SkyWalking:https://github.com/apache/skywalking
- Loki:https://github.com/grafana/loki
- OpenTelemetry:https://github.com/open-telemetry/opentelemetry-java
- kube-prometheus-stack:https://github.com/prometheus-community/helm-charts
💡 学习路径建议
- 入门:本文 + Prometheus 官方文档,2 周能上手
- 进阶:阿里 / Grafana / SkyWalking 博客,理解工业实践
- 实战:用
kube-prometheus-stack部署一套 K8s 监控- 深潜:读 SkyWalking 源码(建议从
apm-sniffer入口),理解字节码增强理论 + 实践 + 源码,缺一不可。
