你好,我是高楼。
从这里开始,我们进入链路追踪改造部分,这节课,我们来看一下怎么在全链路压测项目中选择合适的链路追踪方案。
首先,我们看下这个课程的开源电商项目的部署架构。
从部署架构图中你可以很直观地看到,在微服务架构下,系统的功能是由大量的微服务协调组成的。例如:电商下单业务就需要会员系统服务(mall-member)、认证中心服务(mall-auth)、订单系统服务(mall-order)、购物车系统服务(mall-cart)逐级调用才能完成。而实际在电商企业,每个服务可能是由不同的团队进行开发,部署在成百上千台服务器上的。
这么复杂的调用链路就带来一系列问题:
当系统发生故障的时候,我们需要一种机制对故障点进行快速定位,确认到底是哪个服务、哪个接口出了问题,那么分布式链路追踪技术由此产生。
所谓的分布式链路追踪,就是运行时通过某种方式记录下各服务之间的调用过程,再通过可视化UI方式帮助相关人员快速定位到故障点。 现如今,分布式链路追踪已经成为微服务架构性能监控的底层基础设施,没有它,性能分析人员就像盲人摸象,根本无法彻底了解服务间链路通信的全过程。
而在我的RESAR 性能分析七步法中,分析架构图、拆分响应时间、定向分析都需要借助链路追踪来梳理服务依赖,分析业务核心链路也要用到它。可想而知,链路追踪对性能项目的作用有多大。
知道了链路追踪的重要性,那么,链路追踪应该做成什么样子呢?
总的来说,我们希望链路追踪能够从全局监控到定向监控,从整体维度到局部维度展示各项指标,将跨服务的所有调用链性能信息集中展现出来。这些信息有利于我们度量整体和局部性能,方便我们找到问题产生的源头,极大缩短性能分析时间。
首先,我们需要关注在请求处理期间各个调用的各项性能指标,比如:TPS、响应时间及错误数等。
我们希望从链路追踪中,就可以清晰地看到一个请求对应的每一段的耗时。比如说,一个接口调用另一个接口、Redis、MySQL 等组件时的耗时。当我们发现哪一段耗时比较长的时候,就可以到耗时长的那个组件上,根据定向监控的数据接着往下分析了。
另外,我们对全链路压测标识透传也是有要求的,那就是:
对于跨服务的调用,我们需要对所有涉及到的服务进行一一改造。添加压测标识的属性,以此保证传输中始终带着压测标识。
也就是说,这个压测标记需要在链路追踪中被识别、记录、并传递,这样我们就能做到区分请求(正常流量 & 压测流量)了。
好了,我们先来总结一下,我们希望通过链路追踪达到的目标:
上面我们介绍了链路追踪需要达到的几个主要目标,那么我们又该怎样选择适合自己项目的链路追踪组件呢?
Google Dapper 中已经提到了需要关注的几个主要的方面:
目前业务主流的链路追踪系统,大致功能可以分为以下四大模块:
目前业界流行的链路追踪组件有 Jaeger、Zipkin、SkyWalking 和 Pinpoint 等。但是,这些组件对业务代码的侵入性和不同系统的兼容性都各有其特点。
为了让你有个更为直观的认识,我给你画了个表格,我们一起来看看不同组件的优劣。
从这张对比表可以看出:
总之,每种组件都有它的优缺点,我建议你在选择链路追踪组件的时候,一定要根据自身项目的实际情况,仔细考量哪些地方可以妥协,哪些地方可以放弃,最终选择出一款最适合自己项目的组件。
考虑到我们的电商项目是 Spring Cloud 技术栈,在压测标记跨服务透传上又存在刚性需求,而 Spring Cloud Sleuth 是一套原生的解决方案。
Sleuth 是 Spring Cloud 提供的服务治理模块,在其标准生态下内置了 Sleuth 这个组件。它通过扩展 Logging 日志的方式实现微服务的链路追踪。
利用 Sleuth 服务间原生传递上下文特性,在原有传输上下文的基础上,添加了压测标记的属性,以保证后续跨服务传输中始终带着压测标记。这样也就免去了代码的硬耦合。
Sleuth + Zipkin 是一套成熟的链路追踪解决方案,基于经典 X-B3 Trace 协议 的 Java 接口实现 Brave,使用 Brave SDK,提供了基本的操作 API,手动埋点生成 Trace,如果需要与框架或者项目集成的话,就需要手动添加配置文件或增加代码,它的 instrumentation 子项目,已经提供了 SpringMVC、MySQL、Dubbo 等等的常用组件链路追踪的功能。但是 SDK 埋点的方式,对业务代码存在侵入性,当升级埋点时,必须要做代码的变更。
而性能更好的 Skywalking,依赖 Java Agent 探针,通过字节码注入的方式修改目标方法的字节码,实现调用拦截和数据收集,可以做到真正的无侵入的埋点,在应用程序启动时使用 -javaagent 参数,就可以将探针包注入目标应用程序,完成埋点的植入。对业务代码无侵入的方式,可以做到无感的热升级。用户不需要理解深层的原理,就可以使用完整的监控服务。
但是,从改造难度和成本方面来说,Brave 比字节码注入更容易上手,简单阅读 Skywalking 和 Brave 插件的代码,你就可以发现两者的实现难度有天壤之别。Brave 的代码量很少,核心功能都集中在 brave-core 这个模块下,一个中等水平的开发人员,可以在一天之内读懂它的内容,并且能对 API 的结构有非常清晰的认识。
作为一个专栏项目,我们希望能够尽量能覆盖绝大部分人群,所以最终我们选择了 Sleuth + Zipkin作为链路追踪解决方案。
如果你对 Zipkin 还不是很了解的话,可以参考这篇文章《 快速了解分布式链路追踪系统 Zipkin 》,文中对 Zipkin 的入门知识做了详细的介绍。
说完了链路追踪组件选型,紧接着我们看看如何让它在我们的电商项目中落地?
首先,我们来看一下电商项目集成 Sleuth+ Zipkin 的应用架构。
从架构图中可以看到:我们构建了一个服务网关,通过 API 网关调用具体的微服务,所有的服务都注册到 Nacos 上;当客户端的请求到来之时,网关作为服务端的门户,会根据配置的规则,从 Nacos 中获取对应服务的信息,并将请求反向代理到指定的服务实例。
系统涉及的需要新增/改造业务服务与组件包含以下 10 个:
顺便提下,Zipkin 包括如下的 Transport 方式:
请求量级小的时候,选择 HTTP 方式即可。量级比较大的时候,我们推荐使用 Kafka 消息队列。
而 Zipkin Server Storage 负责存储链路数据,目前支持 Memory、MySQL、Cassandra、ElasticSearch 等数据库,不同数据库的适用环境也不一样:
我们这里将链路日志推送到 Kafka,然后启动 Zipkin Server 聚合日志,监听 Kafka ,如果有新的消息则进行拉取存入到 ElasticSeach,最后再用 Zipkin UI 展示链路过程。
最后,我们再来梳理下整个系统链路追踪改造部分,它大概分为五大部分:
完成这些内容后,整体展示出来的内容如下图所示:
好了,这节课我们讲到这里,我来总结一下:
总之,每种组件都有它的优缺点,在做链路追踪组件的选型时,一定要根据自身项目的实际情况,仔细衡量哪些地方可以妥协,哪些地方可以放弃,从而选择一款适合自己项目的组件。
下一节课,我们将进入实践环节,我会通过案例演示如何应用 Sleuth+Zipkin 来实现链路追踪改造。
在课程的最后,我还是照例给你留两道思考题:
欢迎你在留言区和我交流讨论,我们下节课见!
评论