首页 / 业界 / 正文

链路追踪线上排障实录

上个月帮杭州的一个电商团队救双11的火。 零点刚过,后台涌进来几百条用户投诉,说付完款订单加载不出来。运维盯着监控面板转了三圈,CPU使用率40%,内存剩30%,网关QPS跟往年峰值差了快一半——全绿。 蹲在机房楼梯间抽烟的运维上来骂,说监控全是垃圾。群里产品已经急得连发十几条60秒语音,说要是半小时内解决不了,今年的双11奖金全泡汤。 半小时。 我们几个人对着屏幕愣着。后来还是后端的老周翻了二十分钟零散日志,才揪出来问题:库存服务的超时配置之前测试时从1秒改成了500毫秒,上线忘了改回来,刚好赶上零点的流量峰值,库存接口的平均响应时间是600毫秒,所有请求全超时。但库存服务自己的监控没设超时告警,所以整个面板看起来一切正常。

监控全绿不代表系统没问题

那天我看完他们的整套监控体系,突然就懂为什么会出这档子事。所有的监控都是按服务拆的,订单服务看自己的接口成功率,库存服务看自己的CPU负载,网关看自己的流量曲线,没有一个人能看到从用户点击“提交订单”按钮开始,到整个支付链路走完的全流程状态。
微服务架构单服务监控面板截图
之前很多人觉得链路追踪是个锦上添花的东西,等系统架构稳了、团队规模大了再上就行。真出了问题你就知道,靠人肉翻日志拼请求链路,有多耗时间。那天我们定位那个超时问题,花了整整38分钟。要是有靠谱的链路追踪,输个订单号就能看到库存服务那段红得发黑的超时节点,30秒就能锁死问题根因。

别把自动埋点当万能药

我当时点开他们已经搭了大半年的链路追踪后台,差点笑出声。去年他们跟风上的开源链路追踪工具,给所有服务装了自动探针,就觉得万事大吉。结果我随便找了个最近的下单请求,traceid传到异步库存扣减的线程池里就丢了,同一个请求被拆成了两个完全不相关的trace,拼都拼不起来。 自动探针能覆盖的场景,永远赶不上业务代码的变更速度。比如异步线程的上下文传递、跨消息队列的链路串联、内部自定义的RPC调用,这些自动探针根本识别不到。要是全靠自动埋点凑数,最后拿到的链路图就是个花架子,看着服务之间的箭头连得挺顺,真到排障的时候全是断点。 更离谱的是,他们的链路追踪只埋了服务之间的HTTP调用,中间的数据库查询、Redis缓存读写、甚至调用第三方支付的接口耗时,全没埋。我问他们为什么不埋,技术负责人说,埋点太多了性能损耗大。说实话,为了那点不到1%的性能损耗,换排障的时候少熬几个通宵,这笔账怎么算都值。
完整链路追踪调用耗时分解图
完整链路追踪调用耗时分解图

用得好的链路追踪都是反着来的

很多团队上链路追踪的思路从根上就错了。上来就要做全量埋点,所有生产环境的请求全打trace,存储一上就是几个T。跑了不到半个月,磁盘告警弹得运维烦,直接把老的trace清理周期改成了1天。真出问题的时候,翻出来的记录已经被清没了,白忙活。 真正好用的链路追踪,从来不是追求“全”。比如我们现在自己团队的做法,核心交易链路的trace保留30天,非核心的比如用户评论、头像上传这些,只有出错的请求才留7天,正常请求直接丢,存储成本直接降了70%,一点不影响排障。对吧,你想啊,非核心链路的请求一天几百万条,全存下来除了占磁盘有啥用? 还有,别搞那种所有人都能看的全局链路大面板,上面密密麻麻几百条线绕来绕去,跟电路板似的,除了做汇报的时候好看,实际排障一点用没有。真能用的功能,是你输入一个用户的订单号、或者一个报错的traceid,直接拉出来这个请求从入口到出口的每一个节点——哪一步卡了2.3秒,是查MySQL慢了,还是等下游服务超时,甚至能直接看到节点上的异常堆栈,根本不用挨个服务翻日志。 那天帮他们把链路追踪的断点补完,已经凌晨三点。 外面下着小雨。技术负责人给我递了瓶冰可乐,说之前总觉得链路追踪是要花大价钱做的高大上基础设施,没想到真用起来,核心就是解决实际排障的问题。 对,就是这么回事。别把技术组件搞成什么团队的政绩工程,能帮你在出问题的时候少掉头发的,就是好工具。