20.【学习心得】学习心得-链路日志及埋点

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 【学习心得】学习心得-链路日志及埋点

文档参考:书名:《企业it架构转型之道》-钟华 

网络异常,图片无法展示
|


前文如下:

15.【学习心得】学习心得-传统分布式事务

16.【学习心得】学习心得-cap,base理论

17.【学习心得】学习心得-柔性事务

18.【学习心得】学习心得-柔性事务落地

19.【学习心得】学习心得-大促秒杀活动催生缓存技术的高度使用


   分布式服务体系建设后,整个淘宝平台变成了一个复杂无比的服务交互链路网,如何对每天发生的几千亿次服务调用出现报错时快速定位问题,如何实时监控到服务的运行状态是否正常,如何给运营团队关注的业务指标提供实时呈现以供他们进行实时的精准营销,这一系列的问题都是应用基于分布式服务体系建设后所面对的问题和诉求。

埋点和输出日志

     实现分布式服务跟踪系统的主要思路是通过服务调用链各服务处理节点生成相应的日志信息,通过同一请求中生成的日志具有同一个ID将不同系统或服务“孤立的”日志串在一起,重组还原出更多有价值的信息。

     也就是说,在每一个URL请求都会生成一个全局唯一的ID,称为TraceID,这个ID会出现在该请求中所有服务调用、数据库、缓存、消息服务访问时生成的所有日志中。因为上述所有的资源访问均是在分布式环境下进行的,如何将该TraceID平滑地传递到各个服务节点上呢?如果要求应用程序中实现服务链路日志的打印和TraceID的传递,则在程序中有大量的日志打印代码,而且需要将TraceID采用业务数据的方式传递给下一服务节点,这些都给应用带来了非常大的代码侵入。

     因为阿里巴巴的大部分应用均使用Java语言编写,而且统一通过上文提到的HSF服务框架进行通信,其他如分布式数据库、消息服务、缓存服务等中间件平台在集团层面都进行了很好的统一标准化,所以阿里巴巴采用了另外一种方式,将实现服务调用、各种资源的访问所需要生成服务链路日志,以及TraceID传递等功能的代码(称为埋点)植入到了服务框架层和各资源的访问驱动层,也就是在中间件层面上统一实现了鹰眼的上下文创建以及日志埋点功能,让调用上下文在中间件的网络请求中传递,同时将调用上下文信息保存在了本地ThreadLocal中,从而实现了鹰眼平台所需的调用上下文和日志信息对于应用开发人员完全透明。

网络异常,图片无法展示
|

     图7-6示意了一次请求产生埋点日志信息的流程图,“start Trace”为这次请求产生了上下文信息,即TraceID。关于TraceID的生成规则,可以根据业务的需要在TraceID中包含一定的业务信息,比如前端应用的IP地址,这样可以通过该信息快速定位到生成此次请求的前端应用;比如创建时间,方便后期将修改日志信息按照时间维度进行分区存储。在淘宝的环境中,TraceID一般会包含以下信息:

网络异常,图片无法展示
|


❑IP地址:在淘宝环境可直接映射到前端应用。

❑创建时间:在存储时用于分区。

❑顺序数:用于链路采样。

     除了TraceID负责将URL请求中所有的服务调用和资源访问关系串联在了一起,还有另外一个ID在分布式服务调用过程中也起到非常重要的作用,这个ID就是RCPID,用于标识日志埋点顺序和服务调用间的嵌套关系。


     在实际的业务场景中,服务的调用一定会有顺序性,比如在订单中的金额没有计算完成时,是无法创建支付记录的;也会有服务的嵌套、同步、异步调用,比如订单创建服务中会调用支付中心的接口进行支付记录的创建。通过消息服务的方式,让好几个服务同时执行计算处理,形成了一对多的服务调用,也就是会形成类似树型的服务调用关系。面对这些多样的服务调用场景,如何清晰、准确地记录下各种场景下服务调用间的关系,RCPID的生成方式变得比较重要。

在鹰眼平台中,是通过顺序编号的方式表示服务间的顺序关系,采用如1.1、1.2.1的多级编号方式体现出服务的嵌套和调用关系,以商品订单创建为例(如图7-7所示),图中的数字即为RCPID的示意,鹰眼平台正是通过RCPID还原出一次请求过程中各服务间的调用关系。

网络异常,图片无法展示
|

     在图7-7中的“服务调用”过程中,都会将在前端应用中生成的TraceID和RCPID传递到后端应用1和2的应用实例中,让应用实例在打印埋点日志时能包含这些调用上下文信息,为随后鹰眼服务器通过日志里的这些上下文关键信息获取到同一URL请求引发的一系列服务调用和资源访问,以及这些服务调用的顺序和关系。 埋点日志信息会用于各种不同的分析、统计、监控等场景,除了上文提到的TraceID和RCPID是一定会保存在埋点日志中之外,还需要有其他更多的信息来满足业务对鹰眼监控平台的需求。从鹰眼监控平台多年的发展来看,埋点日志中会包含以下信息。

❑TraceID、RPCID、开始时间、调用类型、对端IP。

❑处理耗时。

❑处理结果(ResultCode)。

❑数据传输量:请求大小/响应大小。

日志收集控制


     应用运行过程中所有的服务调用、资源访问等信息都将保存到埋点日志中,如果在记录这些日志信息的过程中,给应用带来性能的影响,则一定会受到来自应用开发和运营团队的抵触,所以阿里巴巴中间件团队花了大量的功夫优化日志生成所需的系统消耗,将给应用带来的性能影响降到最低,取得的成绩也非常显著。


     但我们发现,有些类型的服务对打印和传输日志带来的性能影响确实非常敏感,特别是在大促秒杀的场景下,短期内产生的海量日志信息确实给整个系统的网络和磁盘IO都带来了不小的冲击。针对这样的情况,我们采用了控制日志收集的方法,也就是在遇到大量请求时只记录其中一部分数据,而不是像平时那样做全量的数据记录。


任何给定进程的消耗和每个进程单位时间的日志采样率成正比,也就是采样率越高,则进程用于日志处理的消耗越高。通过对采样率的调整,可以动态设置针对某一应用实例产生的日志采样率。 你可能会有疑问,如果只收集部分日志信息,会不会有些问题平台就无法捕捉到?从理论上讲,不是100%的日志采样率确实存在漏掉对出现问题的服务调用,但从实际来看,对阿里巴巴这样高吞吐量的线上服务来说是非常有用的,因为那些感兴趣的事件(在大吞吐量的情况下)仍然很有可能经常出现,并且通常足以捕捉到。


     在较低采样率和较低传输负载下,可能会导致错过重要事件,而想用较高的采样率就需要能接受一定的性能损耗。所以在实际的使用中,结合服务调用的频率和业务的访问量,调整适合的日志采样率,找到事件捕捉和性能损耗的平衡点,也是此类跟踪平台需要考虑的问题。

业务全息排查


     服务调用链跟踪功能上线后,成为了平台日常环境中,开发和运维人员用来实时感知服务运行状况以及定位故障和问题的最大利器,但慢慢发现服务调用链跟踪所展现的数据都是服务调用、资源访问等技术方面的数据,无法在调用链跟踪平台中查看到该调用链与之相关的业务信息,比如线上的某次系统调用异常,是由哪笔订单的什么操作引起的?这笔异常订单,是否由卖家对所对应商品的运费模板的某些异常操作导致? 买家A在某段时间内分别进行了哪些操作,每次操作的调用链路是怎样的?这一系列关于订单、商品、买家与调用链间的关系也是开发与运维人员关心的。从实际解决问题的角度,如果有了调用链对应操作的业务信息,对于系统异常的定位会更加精准和快捷。

在这样业务需求的推动下,在服务调用链跟踪功能的基础上,阿里巴巴又实现了“全息排查”的功能。


所谓的全息排查系统,本质上是将服务链路信息与业务事件进行了集成,将业务事件通过服务调用链的traceID&rcpID进行双向关联。当业务事件发生时,在应用代码中将该业务事件所在的服务调用链路、所在服务的信息以及当前业务事件的信息以日志的方式输出,同样基于鹰眼平台中的Tlog日志处理引擎进行统一的日志收集和计算。在阿里巴巴的业务时间日志中包含了以下主要关键信息:

❑“TraceId”将业务事件和鹰眼链路关联在一起的重要ID,用于定位该事件属于哪条鹰眼调用链路。如果日志中没有此字段,通过业务ID将只能查到用户配置的业务信息,但无法反向关联查找出匹配的鹰眼链路。

❑“RpcId”定位该事件在这条调用链路中的位置,比如业务事件发生在哪个服务中。阿里巴巴中间件团队将获取当前上下文的TraceID和RpcID打包成了SDK并封装到了应用运行容器层,应用开发人员只需简单调用EagleEye.getTraceId()和EagleEye.getRpcId()来获取当前上下文中的TraceId和RpcId。

❑“DateKey”该字段为必填,用于记录当前业务事件发生的时间。

❑“业务主键”需要被查询的业务主键字段。比如一行日志中包含了交易订单id,会员id,商品id等,在此处配置一个或多个主键,随后即可在全息排查平台中通过该主键查询出这条日志的相关信息。

❑“业务详细记录”上面的业务主键为查询的主键,业务详细记录则为被存储的键值。

在进行了业务事件日志的输出后,运维和开发人员就能通过“业务轨迹”的方式,在查看某一业务请求服务调用跟踪的同时,也能看到服务中所产生的业务事件以及相关业务主键,如图7-19所示,其中userid、item均为日志中的业务主键。有了业务事件信息的参考,能够更加清晰、快速定位出现异常的服务链路到底是哪一个用户在对哪个商品进行订单创建,可以查看到关键业务值在链路过程中的变化,也可用于业务正确的判断,同时也能从业务的维度进行用户行为的分析。通过全息排查平台,将鹰眼平台从对跨系统调用追踪升级为跨业务领域追踪,走出了从运维平台向运营平台转型的重要一步。

网络异常,图片无法展示
|

业务实时监控


     相信在每年天猫双11的时候,在媒体上播放的非常酷炫的双11实时销售大屏给很多人留下了印象,随着大屏上实时变化和跳动的业务指标,比如实时交易金额、移动端比例、top10的热销商品、top10的商家销售排名等,这些实时业务指标的变化信息不仅能让运营或者商家对销售情况实时掌握,也可以基于这些实时业务数据进行精准类的营销工作。比如平台运营人员发现当前某一区域的移动端用户比例比较低,就可以采用向该区域的手机客户投放一定数量的红包,这在一定程度上可以达到提升移动端用户比例的目的。


     这样的场景其实还有很多,而且我们也发现,有些数据在产生后的一段时间内如果不利用好,就会随着时间的推移其业务价值陡降(如图7-20所示)。比如之前例子中提到的移动端用户实时占比情况数据,在双11结束后再对这些数据进行离线计算和分析,所能发挥的业务价值就会大打折扣。

网络异常,图片无法展示
|

     如何通过发掘数据的最高时效价值,为业务增长进行保驾护航的同时,帮助业务寻求潜在的增长点呢。传统的技术方案有两种,一种是直接访问在线交易数据库,但因为业务大屏展现所需的数据并不是简单地获取单个数据记录,还会产生大量的数据统计、排序、查询、计算等操作,这种方式很显然会对在线交易数据库产生非常大的压力,直接影响到在线交易数据库服务的性能,所以这种方案在实际中很少采用,因为没有人会选择为了实时展现业务指标的变化而牺牲在线数据库的正常服务。另一种方案是将业务数据从在线交易数据库通过ETL的方式同步到数据仓库或其他的数据库中,业务展现大屏通过访问数据仓库获取到相关业务指标和统计数据。这样的方案基本能做到准实时的效果,但如果数据更新量较大,会有较长的数据同步时间,也会给在线数据库带来不少数据同步的压力。 从实际的案例来说,这一类方案能实现的业务指标一般是分钟级。

网络异常,图片无法展示
|

     这次处理的日志就跟服务调用完全没有关系,所有的业务事件(订单成功创建、订单成功支付、用户登录等)日志都要求应用在这些业务事件发生时输出到日志中,再由TLog日志处理平台实现对这些日志从各个应用服务器上的采集,采用TLog提供的图形化日志处理流程的定制,将处理任务下发到流式引擎JStorm中,实现实时对采集到的日志内容进行解析和分类处理,按照业务大屏上所需的数据信息,将不同类型的数据保存到后端的在线数据库HBase或数据库平台中,最后通过API的方式给前端业务展示大屏提供数据的服务,就会实时展示双11的相关数据。

采用这样的方案就使得业务大屏对业务指标的实时展现完全不影响在线交易数据库,也能将发生的业务指标变化在秒级就体现在业务大屏上,有了这样的实时业务大屏,给市场运营人员提供了有价值的参考数据,如实时、精准营销策略或活动时计划等,真正对企业的运营提供了精准有效的数据支持。


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
5月前
|
存储 Go
Go 浅析主流日志库:从设计层学习如何集成日志轮转与切割功能
本文将探讨几个热门的 go 日志库如 logrus、zap 和官网的 slog,我将分析这些库的的关键设计元素,探讨它们是如何支持日志轮转与切割功能的配置。
263 0
Go 浅析主流日志库:从设计层学习如何集成日志轮转与切割功能
|
5月前
|
Kubernetes 容器
k8s学习-CKS真题-日志审计 log audit
k8s学习-CKS真题-日志审计 log audit
153 0
|
5月前
|
存储 缓存 关系型数据库
认真学习MySQL的事务日志-Redo日志
认真学习MySQL的事务日志-Redo日志
66 0
|
10月前
|
存储 监控 数据可视化
小白带你学习linux的ELK日志收集系统
小白带你学习linux的ELK日志收集系统
232 0
|
5月前
|
Kubernetes 监控 容器
k8s学习-CKA真题-监控Pod日志
k8s学习-CKA真题-监控Pod日志
100 0
|
7天前
|
Kubernetes API Docker
跟着iLogtail学习容器运行时与K8s下日志采集方案
iLogtail 作为开源可观测数据采集器,对 Kubernetes 环境下日志采集有着非常好的支持,本文跟随 iLogtail 的脚步,了解容器运行时与 K8s 下日志数据采集原理。
|
2月前
|
JSON 中间件 Go
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
本文详细介绍了如何在Go项目中集成并配置Zap日志库。首先通过`go get -u go.uber.org/zap`命令安装Zap,接着展示了`Logger`与`Sugared Logger`两种日志记录器的基本用法。随后深入探讨了Zap的高级配置,包括如何将日志输出至文件、调整时间格式、记录调用者信息以及日志分割等。最后,文章演示了如何在gin框架中集成Zap,通过自定义中间件实现了日志记录和异常恢复功能。通过这些步骤,读者可以掌握Zap在实际项目中的应用与定制方法
go语言后端开发学习(四) —— 在go项目中使用Zap日志库
|
2月前
|
Java 数据库连接 数据库
后端框架的学习----mybatis框架(6、日志)
这篇文章介绍了如何在MyBatis框架中使用日志功能,包括配置MyBatis的日志实现、使用log4j作为日志工具,以及如何通过配置文件控制日志级别和输出格式。
|
4月前
|
网络安全 数据安全/隐私保护 网络虚拟化
神州数码DCWS学习日志(二)
神州数码DCWS学习日志
24 1
|
4月前
|
Java Apache
学习Java中的日志系统设计与优化
学习Java中的日志系统设计与优化
下一篇
无影云桌面