凌晨三点,CEO 在群里怒吼
2025 年 1 月某个周五晚上,某电商平台的”秒杀”功能崩了。
CEO 在技术群里连发三条语音:”为什么下单要 30 秒?为什么有人能买到,有人一直转圈?你们的监控系统是摆设吗?“
运维团队冷汗直流,打开 Grafana 仪表盘:
– CPU 使用率 45%,正常 ✅
– 内存占用 60%,正常 ✅
– 数据库 QPS 2000,正常 ✅
– Redis 命中率 98%,正常 ✅
但用户就是下不了单。
问题出在哪?没人知道。
因为他们看不见一个请求在 47 个微服务、128 个容器、3 个数据中心之间,是怎么一步步”死掉”的。
这就是微服务时代最残酷的真相:你的监控系统告诉你”一切正常”,但你的用户正在疯狂投诉。
传统监控的三大谎言
谎言 1:”我们有日志,能查到问题”
现实:
– 一次秒杀产生 500 万行日志
– 你要找的那 3 行错误,淹没在 499 万 9997 行 INFO 里
– 当你用 grep ERROR 找到 2000 个错误时,你根本不知道哪个错误导致了用户 A 的订单失败
本质问题: 日志是离散的事件记录,缺乏因果关系。它能告诉你”服务 B 在 23:47:32 报错了”,但不会告诉你”因为服务 A 的第 3 次重试超时,导致服务 B 拿到了脏数据”。
谎言 2:”我们有 Prometheus,能看到所有指标”
现实:
– Prometheus 告诉你”平均响应时间 200ms”
– 但它不会告诉你:为什么 99% 的请求是 50ms,而 1% 的请求要 10 秒?
– 更不会告诉你:那 1% 的慢请求,是因为调用了哪个下游服务的哪个接口
本质问题: 指标是聚合的统计数据,丢失了个体的上下文。它展示宏观健康度,但无法解释具体的故障。
谎言 3:”我们买了 Datadog/New Relic,有 APM”
现实:
– Datadog 的销售给你报价:每月 $15,000 起
– CFO 看了一眼,说:”你们能不能先用开源的顶一顶?”
– 你说能,然后发现开源 APM 有 37 个选项,每个文档都像天书
本质问题: 商业 APM 很强大,但成本高到让中小团队窒息。而开源方案的选型成本,又让人望而却步。
分布式追踪:不是银弹,是手术刀
它到底解决什么问题?
想象你在淘宝下单买了一本书。这个订单的”生命旅程”是这样的:
[你点击下单]
→ [订单服务:创建订单]
→ [库存服务:扣减库存]
→ [支付服务:调用支付宝]
→ [物流服务:生成运单]
→ [消息队列:发送通知]
如果这个订单卡住了,传统监控只能告诉你”某个服务慢了”。
分布式追踪能做什么?
它给这个订单分配一个全局唯一的快递单号(Trace ID),然后在每个服务里盖一个时间戳章(Span):
Trace ID: a1b2c3d4-e5f6-7890
├─ Span 1: 订单服务 [0ms - 50ms]
├─ Span 2: 库存服务 [50ms - 120ms] ← 这里慢了!
│ └─ Span 2.1: MySQL 查询 [60ms - 115ms] ← 罪魁祸首!
├─ Span 3: 支付服务 [120ms - 200ms]
└─ Span 4: 物流服务 [200ms - 250ms]
现在你能一眼看出:库存服务的 MySQL 查询耗时 55ms,拖累了整个链路。
核心概念:只需要懂三个词
- Trace(链路): 一次完整的业务请求,就像一个快递包裹的完整旅程
- Span(跨度): 链路中的一个环节,就像包裹在某个中转站的停留记录
- Trace ID: 全局唯一标识符,就像快递单号,让你能追踪包裹经过了哪些站点
关键洞察: 分布式追踪不是让你看到所有请求,而是让你在海量请求中,精准定位那 0.01% 的异常。
三国杀:Zipkin、Jaeger、SkyWalking 的生死局
Zipkin:被时代抛弃的先驱
身世:
– 2012 年,Twitter 开源了 Zipkin,成为第一个广泛使用的分布式追踪系统
– 2025 年,OpenTelemetry 宣布弃用 Zipkin 导出器
这就像诺基亚发明了触摸屏,却死在了 iPhone 手里。
为什么 Twitter 自己都不用了?
- 仪器化太重: 需要在代码里显式配置拦截器,或者依赖 Spring Cloud Sleuth 自动装配
- 采样策略原始: 只支持固定比例采样(如 1%),无法根据流量动态调整
- 生态边缘化: OpenTelemetry 成为新标准后,Zipkin 的原生数据格式逐渐被淘汰
但它还有价值吗?有。
适用场景:
– 你在维护 2015 年的遗留系统,已经用了 Spring Cloud Sleuth
– 你只是想学习分布式追踪的概念,需要一个极简的 Demo(一个 JAR 包就能跑)
– 你的环境是裸金属服务器,不适合 Kubernetes 的 Sidecar 模式
一句话评价: Zipkin 是分布式追踪的”诺基亚”——它开创了时代,但已经不是这个时代的答案。
Jaeger:CNCF 的宠儿,云原生的标准答案
身世:
– 2015 年,Uber 为了监控数千个微服务开发了 Jaeger
– 2017 年加入 CNCF,随后毕业(Graduated),成为云原生追踪的事实标准
– 2024 年推出 V2 版本,完全基于 OpenTelemetry Collector 重构
如果你的简历里有 Kubernetes,那 Jaeger 就是你的标配。
杀手锏 1:自适应采样
问题: 固定 1% 采样率会导致:
– 低流量服务(如后台管理接口)的 Trace 几乎全部丢失
– 高流量服务(如首页接口)产生海量冗余数据
Jaeger 的方案: Collector 动态计算每个服务/端点的理想采样率,并下发给 Agent:
– 流量激增时,自动降低采样率(如从 10% 降到 0.1%)
– 流量稀少时,自动提高采样率(如从 1% 升到 50%)
用”动态定价”类比:
– 高峰期打折(降低采样率),避免存储爆炸
– 低峰期提价(提高采样率),保证数据可见性
杀手锏 2:Kubernetes Operator 的”自动驾驶”
传统部署的痛苦:
1. 手动在每个 Pod 里配置 Jaeger Agent 的 Sidecar
2. 修改应用的环境变量,指向 Agent 的地址
3. 重启所有 Pod
Jaeger Operator 的魔法:
apiVersion: v1
kind: Pod
metadata:
annotations:
sidecar.jaegertracing.io/inject: "true" # 只需要这一行!
spec:
containers:
- name: my-app
image: my-app:v1.0
Operator 会自动:
– 注入 Jaeger Agent 作为 Sidecar 容器
– 配置网络和环境变量
– 管理 Agent 的版本升级
这是运维的”自动驾驶”。
Jaeger V2:拥抱 OpenTelemetry 的彻底重构
核心变化:
– Jaeger V2 的二进制文件 = OpenTelemetry Collector + Jaeger 特性组件
– 不再维护自己的数据管道,完全使用 OTLP 协议
– 可以直接利用 OTel 的 Processors(批处理、属性修改、PII 过滤等)
战略意义: Jaeger 放弃了”全栈追踪系统”的定位,专注于做 OpenTelemetry 的最佳后端。
适用场景:
– 你的基础设施是 Kubernetes
– 你战略上决定使用 OpenTelemetry 作为唯一采集标准
– 你需要尾部采样或自适应采样来平衡成本
– 你的技术栈偏好 Go 语言编写的组件
一句话评价: Jaeger 是云原生时代的”iPhone”——它定义了标准,并且与生态深度绑定。
SkyWalking:中国开源的逆袭,Java 世界的王者
身世:
– 由吴晟(Wu Sheng)发起,是首个由中国开发者主导的 Apache 顶级项目
– 定位不是”追踪器”,而是全栈 APM 平台(同时解决 Trace、Metrics、Logging)
当你在凌晨 3 点翻文档时,至少不用再忍受机翻的折磨。
黑科技 1:完全无侵入的 Java Agent
Jaeger 的痛点:
– 需要在代码里引入 SDK
– 或者配置 OpenTelemetry 的自动仪器化(还是要改配置文件)
SkyWalking 的魔法:
# 启动应用时,只需要加一行参数
java -javaagent:/path/to/skywalking-agent.jar \
-jar your-app.jar
Agent 做了什么?
– 在 JVM 启动时,使用字节码操作库(Byte Buddy)动态修改已加载的类
– 自动拦截 Spring MVC、Dubbo、MySQL Driver、Redis Client 等框架的方法调用
– 注入追踪逻辑,生成 Span 并发送到 OAP Server
零代码修改,零重新编译。
对比:
– Jaeger:改代码或改配置
– SkyWalking:加一行启动参数
这对遗留系统(Legacy Systems)是救命稻草。
黑科技 2:STAM 流式拓扑分析
传统拓扑生成的问题:
– 依赖离线的大数据分析(如 Spark 任务)
– 延迟高(可能要等 5 分钟才能看到拓扑图)
– 资源消耗大
SkyWalking 的 STAM 算法:
– 无窗口分析: 不依赖时间窗口聚合
– 实时匹配: 利用 Span 中的”对端网络地址”(Peer Network Address)
– 客户端(Exit Span)发起调用时,携带目标 IP
– 服务端(Entry Span)接收请求时,知道自己的 IP
– OAP Server 实时匹配这些 IP,构建依赖关系
用”实时 GPS 导航 vs 事后查地图”类比:
– 传统方案:开完车回家,再看行车记录仪,分析走了哪些路
– STAM:开车时,导航实时显示你在哪条路上
能力延伸: STAM 甚至能识别未安装探针的节点(如 MySQL、Redis、第三方 API),通过推测将其展示在拓扑图中。
黑科技 3:代码级性能剖析
场景: Trace 显示某个 Span 耗时 2 秒,但你不知道是哪行代码慢了。
SkyWalking 的方案:
1. 对该服务实例触发性能剖析(Profiling)
2. 定期对线程栈进行快照(Thread Dump)
3. 将快照可视化为火焰图(Flame Graph)
4. 直接指出是第 347 行代码的 SQL 查询导致了阻塞
从宏观链路直接钻取到微观代码行,这是 Jaeger 做不到的。
原生告警引擎
Jaeger 的痛点: 没有内置告警,需要外挂 Prometheus + Alertmanager。
SkyWalking 的方案: 内置基于规则的告警系统,使用 OAL(Observability Analysis Language) 定义规则:
# 示例:服务 A 的 P99 延迟超过 500ms 且成功率低于 95%
rules:
- name: service_a_slow_and_failing
expression: |
service_percent(service_a, p99) > 500
AND service_sla(service_a) < 95
period: 3 # 过去 3 分钟
action: webhook
适用场景:
– 你的核心业务是 Java(Spring Boot/Cloud)
– 你强烈排斥修改业务代码
– 你需要一套系统同时解决 Trace、Metrics、Log(避免在 Grafana、Kibana、Jaeger 之间切换)
– 你需要服务拓扑图来理解架构,或需要代码级性能剖析
一句话评价: SkyWalking 是 Java 世界的”瑞士军刀”——它不是最纯粹的追踪器,但它是最全能的 APM。
5 分钟选型决策树
graph TD
A[你的技术栈是什么?] --> B{基础设施是 Kubernetes?}
B -->|是| C[Jaeger V2]
B -->|否| D{核心语言是 Java?}
D -->|是| E[SkyWalking]
D -->|否| F{预算极低 or 只是学习?}
F -->|是| G[Zipkin]
F -->|否| C
C --> C1[✅ 云原生标准<br/>✅ OpenTelemetry 原生<br/>✅ 自适应采样]
E --> E1[✅ 零代码侵入<br/>✅ 全栈 APM<br/>✅ 中文文档]
G --> G1[✅ 极简部署<br/>⚠️ 生态边缘化]
一句话决策
| 工具 | 选它的理由 | 不选它的理由 |
|---|---|---|
| Jaeger | 你信仰 CNCF,拥抱 OpenTelemetry,追求标准化 | 你的遗留系统不在 K8s 上,改造成本高 |
| SkyWalking | 你是 Java 老炮,讨厌改代码,需要全栈监控 | 你的技术栈是 Go/Rust,SkyWalking 的 Agent 支持有限 |
| Zipkin | 你在维护 2015 年的遗留系统,或只是想学习概念 | 你在构建新系统,Zipkin 已经不是最佳选择 |
2025 年的终极真相:OpenTelemetry 统治一切
游戏规则已经改变
过去(2020 年之前):
– 每个追踪系统都有自己的 SDK、数据格式、传输协议
– 选了 Zipkin,就被 B3 协议绑定
– 选了 Jaeger,就被 Jaeger Client 绑定
– 迁移成本 = 重写所有仪器化代码
现在(2025 年):
– OpenTelemetry 统一了采集层
– 所有应用只需要集成 OTel SDK
– 后端可以随时切换(Jaeger、SkyWalking、Tempo、甚至商业 APM)
类比: OpenTelemetry 就像 USB-C 接口,你的手机、电脑、耳机都用同一个接口,充电器可以随便换。
三大工具的应对策略
Jaeger:彻底拥抱
- V2 版本 = OTel Collector + Jaeger 后端
- 放弃维护多语言客户端,专注于存储、查询、可视化
- 战略: 成为”OTel 的最佳后端”
SkyWalking:兼容并包
- 既支持 OTel 协议的数据摄入
- 也坚持发展自己的探针(Java Agent、eBPF Rover)
- 原因: OTel 只关注通用采集,SkyWalking 的探针能采集更深层的语言运行时信息
Zipkin:逐渐边缘化
- OTel 弃用 Zipkin 导出器
- 虽然可以通过适配器继续使用,但在新技术栈中已不是首选
未来预测(2026-2027)
- Jaeger 会变成”OTel 生态的默认后端”(类似 Prometheus 之于 Metrics)
- SkyWalking 会继续深耕语言运行时监控和 eBPF(差异化竞争)
- Zipkin 会成为”教学工具”和”极简场景的备胎”
今晚就能动手的三件事
1. 如果你在用 Kubernetes:部署 Jaeger(5 分钟)
# 安装 Jaeger Operator
kubectl create namespace observability
kubectl apply -f https://github.com/jaegertracing/jaeger-operator/releases/download/v1.53.0/jaeger-operator.yaml -n observability
# 部署 Jaeger 实例
cat <<EOF | kubectl apply -f -
apiVersion: jaegertracing.io/v1
kind: Jaeger
metadata:
name: my-jaeger
namespace: observability
spec:
strategy: allInOne
storage:
type: memory
EOF
# 访问 UI
kubectl port-forward -n observability svc/my-jaeger-query 16686:16686
# 打开 http://localhost:16686
2. 如果你在用 Java:体验 SkyWalking(10 分钟)
# 下载 SkyWalking Agent
wget https://archive.apache.org/dist/skywalking/java-agent/9.0.0/apache-skywalking-java-agent-9.0.0.tgz
tar -xzf apache-skywalking-java-agent-9.0.0.tgz
# 启动你的应用(只需加一行参数)
java -javaagent:/path/to/skywalking-agent/skywalking-agent.jar \
-Dskywalking.collector.backend_service=127.0.0.1:11800 \
-jar your-app.jar
# 启动 SkyWalking OAP + UI(Docker)
docker run -d --name skywalking \
-p 8080:8080 -p 11800:11800 \
apache/skywalking-oap-server:9.7.0
3. 如果你只是好奇:30 秒体验 Zipkin
docker run -d -p 9411:9411 openzipkin/zipkin
# 打开 http://localhost:9411
最后一句话
不要等到系统崩了才想起可观测性。
微服务的复杂度不会因为你忽视它而消失,只会在凌晨三点以”CEO 怒吼”的形式爆发。
现在就去装一个追踪系统,哪怕只是在测试环境。
因为当你能看见请求在系统里的每一步旅程时,你就不再是”救火队员”,而是”上帝视角的架构师”。
参考资料
本文技术细节参考了以下权威资料:
1. Google Dapper 论文(2010)
2. Jaeger 官方文档 v1.76
3. Apache SkyWalking 官方文档 v9.7.0
4. OpenTelemetry 规范 v1.30
5. CNCF 2025 可观测性调研报告









AI周刊:大模型、智能体与产业动态追踪
程序员数学扫盲课
冲浪推荐:AI工具与技术精选导航
Claude Code 全体系指南:AI 编程智能体实战
最新评论
Flash版本的响应速度确实提升明显,但我在使用中发现对中文的理解偶尔会出现一些奇怪的错误,不知道是不是普遍现象?
遇到过类似问题,最后发现是网络环境的问题。建议加一个超时重试机制的示例代码。
谢谢分享,我是通过ChatGPT的索引找到这里来的。
十年打磨一个游戏确实罕见,这种专注度在快节奏的游戏行业很难得。从Braid到The Witness,每作都是精品。
快捷键冲突是个很实际的问题,我自己也被这个问题困扰过。最后通过自定义快捷键组合解决了。
会议摘要这个功能很实用,特别是对经常需要参加长会议的人。不过三次免费使用确实有点少了。
硕士背景转AI基础设施,这个路径其实挺常见的。建议多关注底层系统知识,而不只是模型应用层面。
配置虽然简单,但建议补充一下认证和加密的注意事项,避免被中间人攻击。