43

链家全链路跟踪平台 LTrace 设计实践

 5 years ago
source link: https://mp.weixin.qq.com/s/CAC1zG0nX3yMKqwuL2d2jQ?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

当今的互联网服务,通常都是用大规模的分布式集群来实现的。服务可能来自不同的研发团队、使用不同的编程语言来实现、运行在上千台服务器上。随着链家的业务发展,公司的分布式系统变得越来越复杂,用户的一次请求通常由多个系统协同完成处理,而且这些处理是发生在不同机器甚至是不同集群上的,当请求处理发生异常时,需要快速发现问题,并准确定位到是哪个环节出了问题,这是非常重要的。

作者|李宝银

编辑|蔡白银

网址|tech.lianjia.com

微信公众号|链家产品技术团队

当今的互联网服务,通常都是用大规模的分布式集群来实现的。服务可能来自不同的研发团队、使用不同的编程语言来实现, 运行在上千台服务器上。

随着链家的业务发展,公司的分布式系统变得越来越复杂,用户的一次请求通常由多个系统协同完成处理,而且这些处理是发生在不同机器甚至是不同集群上的,当请求处理发生异常时,需要快速发现问题,并准确定位到是哪个环节出了问题,这是非常重要的。

vqUZZjy.jpg!web

为了解决这样的问题,我们经过调研与测试,结合业界的实践经验 开发了LTrace链家全链路跟踪平台,有效应对上面的问题,大幅度提升工作效率。目前已经在公司多部门的各条业务线项目中得到成功应用。基于请求链路采集到的全量丰富数据,我们能够直观的了解到项目间的链路关系,就能够进行问题的快速定位与瓶颈节点的快速排查,代码性能问题一览无余。

链路跟踪,关键的核心是调用链,就是对一次请求进行跟踪。通过为每个请求生成一个全局唯一的ID,将分布在各个服务节点上的同一次请求串联起来,还原出更多有价值的数据。在 我们设计实现LTrace平台过程中,遇到几项大的挑战。

  1. 稳定性挑战。我们的业务 系统对于稳定性、性能、资源要求极其严格,不能有太复杂的逻辑和外部依赖,并对业务系统性能几乎无影响,LTrace平台的稳定性不应该对业务系统的稳定性造成任何影响;

  2. 高性能挑战。目前公司存在 众多复杂的分布式业务系统,数十 亿hits 生成的链路数据需要及时采集存储, 这就要求LTrace平台具备快速的数据处理能力

  3. 透明、易扩展、避免侵入业务。易于被使用方广泛接受、低耦合是很重要的,透明性用来隐藏实现策略,避免让使用者卷进细节,同时 具备良好的可扩展性

  4. 跨语言、多协议。在公司各部门中,存在JAVA、PHP等众多异构系统以及各种服务中间件,因此LTrace平台要实现全链路跟踪,必须要支持跨语言、多协议。

功能简介

一, 调用链路

我们通过对一次请求进行还原,形成一个完整的调用链路图,如下图。界面中展示请求依次通过的各个服务节点的情况。比如请求经过每个服务节点的IP、发送与响应时间点、处理结果与处理时长,网络传输时长、异常描述等信息。

QB3ieef.jpg!web

二,问题快速定位

再比如,我们现在可以在界面中快速的定位到问题出现的服务节点、机器IP与问题原因。以前我们遇到线上问题时,通常需要同时登录N台机器抓日志排查,有时还可能需要关联上下游项目一起排查。 

j6fAver.jpg!web

三,瓶颈节点

再次,我们还能够快速定位瓶颈节点。如界面中红框部分显示的是链路调用的瓶颈节点,由于该节点的耗时,导致了整个链路调用的耗时延长,因此针对该节点进行优化,进而达到优化整个链路的效率。

EVFVneJ.jpg!web

四,代码优化

除此,我们还能够检测到代码中一些需要优化的地方。比如图中红框部分都是同一个接口的调用,甚至连请求参数都是一样的。这种调用如果优化成批量请求或者相同参数只请求一次,能够快速提升节点的服务质量。

bmYZZnr.jpg!web

对系统行为进行链路跟踪必须是持续进行的,因为异常、超时等的发生是无法预料的,异常超时可能发生在链路的任何一个节点上或者一次调用的网络中,而且可能是难以重现的。同时跟踪需要是无所不在,遍布各处的,否则可能会遗漏某些重要的点。基于此LTrace设计了三个最重要的设计目标:极低的额外开销,对应用的透明性,可扩展。同时产生的跟踪数据需要可以被快速分析,这样可以帮助我们实时获取各节点状态。

平台设计

一,平台架构

FJnyaev.jpg!web

上图中,LTrace平台架构主要分为三部分:数据埋点上报、数据实时存储、数据前端展示。

  1. 左侧部分使用埋点中间件完成数据的采集,并异步写入到本地trace文件,通过rsyslog发送数据到消息服务中。至于采样策略,后面会有详细介绍

  2. 中间部分数据汇集并存储,接受消息队列中数据并存储到Hbase与ES中。

  3. 右侧部分在界面中检索数据,分析数据进行展示。

二,基本概念

TraceId :全局唯一,用于标识一次请求,会在RPC调用的网络中传递。

SpanId :签名方式生成:0, 0.1, 0.1.1, 0.2。用于标识一次RPC在分布式请求中的位置,比如0.2就是0节点服务调用的第二个服务。

Annotation :基本标注列表,记录一次RPC生命周期中重要时刻的数据快照。

BinaryAnnotation:业务标注列表,如果项目需要带上业务数据(比如电话号码、UserId等),可以将需要的数据放入。

三,调用链-Trace树

我们将一次请求所形成的调用链路,标记成一棵Trace树,并用全局唯一的TraceId来标记这棵树,如下图:

N36RRja.jpg!web

四,调用链-Span节点

对于一次分布式请求,总会存在多次调用关系(如图中箭头线),我们将每次调用(箭头线)标记成一个Span节点,并用SpanId来标记这个Span节点。

UZneUry.jpg!web

五,数据埋点

LTrace平台对应用开发者近乎零侵入,通过为不同的异构系统提供对应的埋点中间件(如JAVA、PHP等)完成链路跟踪。在埋点中间件,生成统一的TraceId等核心数据,并收集比如调用类型、机器IP、服务名称、耗时、层级关系、异常信息、业务系统的自定义数据等。

在一次分布式请求中,都有四个埋点阶段,如下图。

qYvUzm6.jpg!web

  1. 客户端发送(Client Send):客户端发起请求时埋点,需要传递一些参数,比如TraceId、SpanId等;

  2. 服务端接收(Server Receive):服务端接受请求时埋点,回填一些参数,比如TraceId、SpanId等;

  3. 服务端响应(Server Send):服务端返回请求时埋点,将埋点数据传递到后端线程;

  4. 客户端接收(Client Receive):客户端接受返回结果时埋点,将埋点数据传递到后端线程;

六,示例

接下来我们通过一个示例进行详细描述,如下图,对于一次分布式请求,TraceId=12345。

在应用A收到客户端请求时刻为0ms,响应请求时刻为69ms,即是本次请求耗费时长69ms

u63Ybar.jpg!web

七,数据存储

调用链路数据的实时查询主要是通过Hbase,使用traceID作为RowKey,SpanId + Type(c代表客户端、s代表服务端)能天然的把一整条调用链聚合在一起,提高查询效率。

vu2IFvM.png!web

一,低开销与采样

低开销是LTrace的一个关键的设计目标,如果一个工具价值未被证实但又对性能有影响的话,用户通常不会接受它。采样可以降低开销,但是简单的采样可能导致采样结果无代表性,LTrace通过提供多种采样机制来满足性能和代表性两方面的需求。

QrErU3Z.jpg!web

最初我们的默认采样策略很简单,是在每100个请求中选择一个进行跟踪,这种策略对于那种请求量很高的服务来说,可以保证跟踪到有价值的信息;但对于那些负载不高的服务来说,可能会导致采样频率过低,从而遗漏重要信息,因此我们提供了自定义采样策略;对于异常、超时等这类极端的情况,我们认为这类数据非常有价值,因此我们决定在极端情况下全采样;另外,对于测试人员,我们提供了可对一次请求显示指定采样。这样采样就既灵活又高度可控。

此外,通过优化消息、缓存、存储结构、批量异步写入等方式,平台性能得到大幅度提升。

通过以上采样策略与性能优化手段,我们只需要线上原来几十分之一的机器数量,就能够实现原来数十倍机器相同的效果。

二,日志TraceId绑定

  1. 我们通常为了便于在日志中跟踪一次请求,一般做法是在项目收到请求的入口放入一个RequestId。现在,应用方可以将TraceId绑定到日志中,通过这个TraceId我们不仅能够将应用内一次请求给串联起来,同时还能够用这个TraceId到上下游应用中去进行串联。

  2. 有时为了知道接口都有哪些上游在使用,通过在日志中记录调用方来源。LTrace就能够解决这个问题,通过在每次请求中输出当前请求已经过的应用名称列表,我们不仅能通过日志就能够识别这个请求的上游,还能知道这个请求所经过的所有上游应用以及请求入口。

emmyemj.jpg!web

三,支持自定义TraceId

为便于研发、测试人员进行线上线下问题的调试、排查,LTrace平台支持传递自定义TraceId,通过TraceId对问题进行跟踪。

qQ7je2b.jpg!web

四,支持多线程等场景

业务系统中,可能会存在一些对线程池的使用场景,而线程池的切换对于TraceId的传递是很困难的。在LTrace平台中,我们提供了显示API的支持方式,保证在多线程的场景下TraceId也能进行上下文传递。

五,业务方接入简单,稳定可靠

  1. 业务方接入LTrace平台,只需要花费几分钟阅读使用文档,添加几行配置,就能够投入使用。

  2. Trace系统的可用性能够达到99.99%以上,业务系统的稳定性不依赖LTrace平台的稳定性,即使LTrace平台出现异常,也不会对业务系统的稳定性造成任何影响。

经验总结

  1. 使用LTrace平台,我们可以理清系统之间关系,帮助找到关键系统路径上的请求延迟,解决并提高整体性能;

  2. 分析请求是否正确发送给了服务提供者,进行正确性检查;

  3. 同时我们还将LTrace与公司的监控系统进行集成,如果异常发生了,我们会生成包含TraceId在内的详细异常数据并上报给监控系统,监控服务立即发出实时的问题报警,这样可以帮助快速发现异常以及异常的情况。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK