
上周,一个做微服务的朋友找我吐槽。他们的订单系统最近经常“抽风”——用户下单后,偶尔要等好几秒才能看到结果。监控显示,下单接口的P99延迟从200ms飙到了3秒。
他们翻遍了日志,没找到规律。看APM的火焰图,只知道“订单服务慢”,但订单服务里有十几个函数,不知道是哪个函数慢。更崩溃的是,这个慢请求只影响1%的用户,在测试环境根本复现不出来。
他说:“我知道它慢,但我不知道它为什么慢。”
我说:“你可能需要两样东西:分布式追踪和性能剖析。”
这就是云上可观测性的进阶玩法。指标告诉你“慢了”,日志告诉你“报错了”,但追踪和剖析才能告诉你“慢在哪一行代码”。
01 追踪不是万能的
很多人以为,上了分布式追踪(比如Jaeger、SkyWalking)就能解决所有性能问题。这是第一个误会。
追踪能告诉你什么?一个请求从入口到各个服务,每一步花了多少时间。比如:API网关20ms,订单服务800ms,库存服务50ms,支付服务30ms。好了,你知道是订单服务慢了。
然后呢?订单服务里有一堆代码:参数校验、业务逻辑、数据库查询、缓存读写、外部API调用……你不知道是哪个函数拖了后腿。
这就是追踪的边界:它能看到服务之间,看不到服务内部。
追踪告诉你“谁慢了”,但只有性能剖析(Profiling)能告诉你“为什么慢”。
02 剖析:给代码拍CT
性能剖析不是新概念。早在单机时代,我们就有perf、gprof。但在云原生环境下,剖析有了新的玩法——持续剖析。
传统剖析是“拍照片”:出问题了,登录服务器,跑一下profiler,看看CPU热点在哪。问题是,偶发问题你抓不到,生产环境你不敢随便跑。
持续剖析是“拍视频”:在后台一直跑,以极低开销持续采集性能数据。你可以回溯到任何一个时间点,看看当时哪段代码在消耗CPU、哪段在等待IO、哪段在申请内存。
这就是为什么它能解决我朋友的困境。那个1%的慢请求,在追踪里能看到是订单服务的某次调用慢了,再切到持续剖析,看那个时间点的CPU火焰图,发现是某个JSON序列化函数占了80%的CPU——原因是用户传了一个超大购物车,序列化耗时暴涨。
反常识观点:性能瓶颈往往不在数据库,不在网络,在你以为很快的代码里。 只有剖析能把它揪出来。
03 追踪与剖析:1+1>2
追踪和剖析单独用都有局限,合起来才叫可观测性。
追踪:给你调用链,知道问题在哪个服务的哪个接口。
剖析:给你代码级热点,知道问题在接口里的哪一行。
组合拳怎么打?
第一步,从APM或追踪系统里,找到慢请求的Trace ID和发生时间。
第二步,在持续剖析系统里,按时间切片,找到那个时间段的CPU火焰图或内存分配图。
第三步,定位到具体函数,甚至具体代码行。
第四步,修复代码,上线验证,再回来看火焰图是否改善。
我见过一个团队,用这套方法找到了一处“每次请求都重新加载配置文件”的bug。之前他们一直以为是数据库慢,加了缓存、加了索引,都没用。最终发现是配置文件解析占了40%的CPU。
这个bug,追踪看不出来,指标看不出来,日志看不出来。只有剖析能看出来。
04 工具怎么选?
云上可观测性工具分几类,按需组合。
分布式追踪:
Jaeger:CNCF毕业项目,功能成熟,支持OpenTelemetry,适合自建。
SkyWalking:国内用得很多,除了追踪还有指标和日志,一体化方案。
Zipkin:老牌项目,轻量,适合小规模。
持续剖析:
Pyroscope:开源持续剖析项目,支持多种语言,和Grafana集成好。
Parca:Polar Signals出品,专注持续剖析,和Prometheus生态兼容。
Datadog Continuous Profiler:商业方案,和APM深度集成,体验好但贵。
云厂商方案:AWS CodeGuru Profiler、阿里云应用监控(ARMS)也提供剖析能力。
全栈方案(追踪+指标+日志+剖析):
Grafana Cloud:整合了Prometheus、Loki、Tempo、Pyroscope,一套搞定。
Datadog:商业产品的标杆,但价格也感人。
云原生组合:OpenTelemetry采集 + Jaeger追踪 + Prometheus指标 + Pyroscope剖析 + Grafana展示。
小团队可以先从开源组合开始,用OpenTelemetry统一采集,省掉改代码的痛苦。
05 落地三件事
如果现在开始,可以从这三件事入手。
第一件事:统一Trace ID
这是可观测性的基石。确保所有服务都传递同一个Trace ID,并把它打印到日志里。这样你才能从追踪跳到日志,从日志跳到剖析。
OpenTelemetry帮你搞定这件事,不用每个语言自己实现。
第二件事:选一个持续剖析工具
不用追求全量剖析。先从CPU剖析开始,选一个能和生产环境共存、开销可控的工具。Pyroscope的采样开销通常在1%以内,完全可以接受。
第三件事:建一个“慢请求排查SOP”
把“发现慢请求 → 查追踪 → 定位到服务 → 查剖析 → 定位到代码行”这个流程写成文档,让团队所有人都知道怎么用这套工具。
我见过一个团队,工具都装好了,但没人会用。出了故障还是老办法:翻日志、看监控、猜。后来建了这个SOP,新人入职第一周就学,效率明显提升。
06 一个真实案例
去年帮一个SaaS公司优化性能。他们的核心报表接口,P99延迟经常飙到5秒以上,但平均延迟只有200ms。说明有少数请求特别慢。
追踪显示,慢请求都卡在一个叫“数据聚合”的服务里。但那个服务代码几千行,不知道哪里慢。
我们部署了持续剖析,抓到一个慢请求的CPU火焰图。一看,一个叫“字段映射”的函数占了70%的CPU。翻代码,发现每次请求都会从一个巨大的配置文件里加载字段映射表,而不是用缓存。
改了一行代码,把映射表缓存起来。上线后,P99延迟从5秒降到300ms。那个月的账单里,CPU费用降了30%。
运维负责人说:“以前觉得性能优化就是加机器,现在才知道,有时候是代码里的一行缓存。”
写在最后
回到我那个做微服务的朋友。后来他们上了持续剖析,用了一周,找到了那个慢请求的原因:用户传了超大购物车,序列化时没做限制。
改了一行代码,限制购物车最大商品数量。上线后,慢请求消失了。
他跟我说:“以前觉得可观测性就是监控、日志、告警,现在才知道,后面还有更深的玩法。”
可观测性不是“出了问题再看”,而是“出了问题能快速找到原因”。追踪告诉你“谁慢了”,剖析告诉你“为什么慢”。两者加起来,你才能从“知道它慢”到“知道怎么修”。
你的系统里,有没有那种“知道慢但不知道哪里慢”的请求?今天就可以试试,找一个慢请求,用追踪定位到服务,再用剖析定位到代码行。
你会看到以前看不到的东西。