LabHub
学习 学习路径 课程

微服务架构

指标回答不了的问题

在 LabHub 中继续学习

一句话总结

各服务单独快速的实际和,它们按顺序通过的一个请求很慢的事实并不矛盾。

流程图: 如何选择几乎决定了跟踪的价值。 · 缓慢的请求和失败的请求也以相同的概率被抛弃。 · 结束后 · 同一轨迹的范围用同一收集器

为什么需要这个?

收到了报告说结算画面需要2秒钟。网关p99上升到1.8秒。依次打开后面的10个服务的p99,全部正常。

在这种情况下,指标在原则上无法给出答案。因为指标是统计值,无法恢复单个请求的路径。无法保证服务A的p99和服务B的p99是同一请求。需要的不是每个服务的统计数据,而是请求的整个路径。

怎么行动

Trace是一个共享一个Trace ID的Spans的树。每个Spans都有名称、开始·结束时间、父Spans ID、属性和类型(kind)。类型在实际工作中很重要——SERVER是接收方,CLIENT是呼叫方。CLIENT Spans和SERVER Spans的时间差是网络和队列消耗的时间,两者都需要才能知道该值。

制作这个树的唯一机制是上下文传播。标准头是W3Ctraceparent格式如下。

traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
             ^버전 ^트레이스 ID(32hex)            ^부모 스팬 ID(16hex) ^샘플 플래그

Trace ID在整个请求中保持不变,Span ID在每个跳跃中都不同。只要遵守这两种规则,就可以将日志与Trace ID关联起来,这就能解决一半的问题。

跟踪回答的问题有三个。首先,一个请求在哪里花费了时间。如果每天数百万人次中只有1%的优惠券查询花费了1,612ms,那么平均仪表盘也不会动弹。其次,重复调用问题。即使单个查询是4ms,如果一个请求执行340次,那么1.4秒。只有在需要计算范围的情况下才会看到这一点。第三,条件路径——只有在特定租户、特定标志、特定缓存丢失组合的情况下才会变慢。

在现场相遇的样子

传播中断的点几乎已经确定。自动计量无法涵盖的自有HTTP客户端、将任务转发到线程池或工作者的代码、消息队列以及删除头部的第三方代理。如果跟踪异常短,请从这四个地方开始查看。

也值得了解一个概念,即自有耗时(self time)。它是一个范围的整个持续时间中减去子范围时间的值。如果这里很大,就意味着隐藏着自动计量无法看到的流程工作——串行化、排序、压缩——。

即使在完成所有跟踪之前,至少也要输入相关性ID。在请求进入点创建ID,在所有日志中输入该字段,并在所有子调用头中携带发送。仅此一项就能极大地缩短故障调查时间。

如何确定采样

如果保存所有请求的跟踪,成本无法承受。所以只保留一部分,如何选择几乎决定了跟踪的价值。

最简单的方法是收到请求时按照确定的比例掷骰子。虽然实现简单,可以预测成本,但有一个决定性的弱点。**缓慢的请求和失败的请求也以相同的概率被抛弃。**调查的对象正是这些请求。如果采样1%,那么在100个有问题的请求中只剩下1个。

所以出来的就是在请求结束后决定是否留下的方式。在轨迹完成之前暂时收集起来,如果慢了或者有错误的话就留下或者扔掉。虽然可以准确留下想要的东西,但有代价。因为必须记住整个轨迹,所以收集器方面需要内存和状态,如果收集器数量根据规模增加,就需要根据路径调整,让同一轨迹的范围用同一收集器

在实际工作中,通常会把两者混合在一起。基本是以较低的比例混合,得到日常的画,如果出现错误或请求太慢,就一定会留下。而且**决定只在请求的最前面做出一次,然后用标题传播结果。**如果每个服务单独掷骰子,则从中间开始断开轨迹,留下无法使用到任何地方的碎片。traceparent的最后标志所做的事情正是这个。

还需要确定的一点是保存期限。轨迹的数量比日志还要多,所以很难保持长久。相反,从轨迹中提取的指标可以保存很长时间,所以将原件存放几天,根据服务和路径提取延迟分布作为指标进行长期保存组合是没有问题的。对于与几个月前相比的问题,指标会回答,对于现在这个请求为什么很慢,轨迹会回答。

下次实习要做的事情

推出3段链式服务traceparent直接制作并传播。验证格式,确认每个跳跃的span ID是否发生变化,将三个服务的日志连接到trace ID,找到传播中断的点,最后计算最慢的区间和自身所需时间。