写点什么

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

  • 2019-09-20
  • 本文字数:3712 字

    阅读完需:约 12 分钟

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

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

背景

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


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



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


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


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

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

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

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

功能简介

一, 调用链路

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


二,问题快速定位

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


三,瓶颈节点

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


四,代码优化

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



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

平台设计

一,平台架构


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


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


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


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

二,基本概念

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


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


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


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

三,调用链-Trace 树

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


四,调用链-Span 节点

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


五,数据埋点

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


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



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

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

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

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

六,示例

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


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


七,数据存储

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


特性

一,低开销与采样

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



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


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


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

二,日志 TraceId 绑定

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

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


三,支持自定义 TraceId

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


四,支持多线程等场景

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

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

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


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

经验总结

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

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

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


本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。


原文链接:


https://mp.weixin.qq.com/s/CAC1zG0nX3yMKqwuL2d2jQ


2019-09-20 14:331994

评论

发布
暂无评论
发现更多内容

LiteOS内核源码分析:静态内存Static Memory

华为云开发者联盟

内存管理 LiteOS 静态内存 Static Memory Membox

负载均衡续:万亿流量场景下的负载均衡实践

Coder的技术之路

负载均衡 架构 高并发 负载均衡架构

用机器学习操控无人驾驶小车,竟然和训练狗狗的原理一样!?

亚马逊云科技 (Amazon Web Services)

百分点大数据技术团队:政务数据安全管理实践

百分点大数据团队

Flink on Zeppelin 系列之:Yarn Application 模式支持

Apache Flink

flink

【案例】新基建下星环科技城轨智能视频分析系统建设

星环科技

云图说|云数据库MySQL内核小版本升级全攻略

华为云开发者联盟

MySQL 云数据库 内核 华为云数据库 小版本升级

从简历被拒到收割8个大厂offer,我用了3个月成功破茧成蝶

比伯

Java 编程 架构 面试 计算机

专家解惑 | 关于华为云盘古大模型,你想问的都在这里~

华为云开发者联盟

计算机视觉 nlp 华为云 盘古大模型 预训练

yarn的多租户配置实现资源隔离

五分钟学大数据

YARN

高并发之存储篇:关注下索引原理和优化吧!躲得过实践,躲不过面试官!

Coder的技术之路

数据库 高并发 索引结构 索引优化

GitHub Actions:真正的 DevOps CI

大龄程序员老羊

架构 DevOps 持续集成 Github Actions NoOps

数据仓库分层架构及元数据管理

五分钟学大数据

数据仓库

HDFS的HA以及Yarn的HA高可用

五分钟学大数据

hdfs YARN 5月日更

zookeeper的架构

大数据技术指南

zookeeper 5月日更

架构训练营-作业三(消息队列详细架构设计文档)

eoeoeo

架构实战营

回顾 Alex Smola 讲述的“自动化机器学习(AutoML)”,本文带你了解 AutoGluon!

亚马逊云科技 (Amazon Web Services)

高并发系列:存储优化之也许可能是史上最详尽的分库分表文章之一

Coder的技术之路

高并发 分库分表 高并发系统设计

流媒体:依托于声网的连麦解决方案

小岛上的黑桃六

架构 音视频 架构师 流媒体 声网

Android中绘制圆角的三种方式

teoking

android

大四实习生”都四面成功拿到字节跳动Offer了,你还有什么理由去摸鱼?

学Java关注我

Java 编程 架构 面试 计算机

HDFS

xujiangniao

GitHub开源的最全中文诗歌古典文集数据库

不脱发的程序猿

GitHub 开源 程序人生 中华古典文集数据库

万丈高楼平地起,爆肝21000字Java基础知识总结,收藏起来总有用得着的时候

北游学Java

Java 集合 线程池 IO流

架构师实战营,模块三:架构设计详细文档

ifc177

#架构实战营

架构实战营模块三作业

日照时间长

架构实战营

【LeetCode】解码异或后的数组Java题解

Albert

算法 LeetCode 5月日更

INNOVATE 2021 圆满落幕,一起盘点那些 AI 前沿实例!

亚马逊云科技 (Amazon Web Services)

高并发系列:架构优化之从BAT实际案例看消息中间件的妙用

Coder的技术之路

高并发 高并发系统设计 消息队列 消息中间件

Java面试:BIO,NIO,AIO 的区别,别再傻傻分不清楚

Java大蜗牛

Java 程序员 面试 编程语言 后端

YARN资源调度三种模型介绍

五分钟学大数据

YARN

LTrace-链家全链路跟踪平台设计实践_架构_李宝银_InfoQ精选文章