分布式链路追踪系统深入理解

背景

对于普通系统或者服务来说,一般通过打日志来进行埋点,然后再通过elk进行定位及分析问题,更有甚者直接远程服务器,使用各种linux命令单手操作查看日志,说到这,我也没摆脱这种困境。那么随着业务越来越复杂,企业应用也进入了分布式服务化的阶段,传统的日志监控等方式无法很好达到跟踪调用,排查问题等需求。

总之,在各种服务之间调用:

  1. 如何快速发现问题?
  2. 如何判断故障影响范围?
  3. 如何梳理服务依赖以及依赖的合理性?
  4. 如何分析链路性能问题以及实时容量规划?

如何在分布式服务进行日志监控呢?首先大家会想到分布式链路追踪系统,说到这,就得讲 OpenTracing 规范,OpenTracing 是一个轻量级的标准化层,它位于应用程序/类库和追踪或日志分析程序之间。详细介绍见 opentracing文档中文版。

在谷歌论文《 Dapper,大规模分布式系统的跟踪系统》的指导下,许多优秀的APM应运而生。分布式追踪系统发展很快,种类繁多,给我们带来很大的方便。但在数据采集过程中,有时需要侵入用户代码,并且不同系统的 API 并不兼容,这就导致了如果您希望切换追踪系统,往往会带来较大改动。OpenTracing为了解决不同的分布式追踪系统 API 不兼容的问题。


技术调研指标

面对各种链式追踪系统开源,我们要如何选择:

我们主要关注在请求处理期间各个调用的各项性能指标,比如:吞吐量(TPS)、响应时间及错误记录等。

  1. 吞吐量,根据拓扑可计算相应组件、平台、物理设备的实时吞吐量。
  2. 响应时间,包括整体调用的响应时间和各个服务的响应时间等。
  3. 错误记录,根据服务返回统计单位时间异常次数。

全链路性能监控 从整体维度到局部维度展示各项指标,将跨应用的所有调用链性能信息集中展现,可方便度量整体和局部性能,并且方便找到故障产生的源头,生产上可极大缩短故障排除时间。

我们除了性能指标之外,我们也需要链式追踪系统拥有以下功能:

  1. 请求链路追踪,故障快速定位:可以通过调用链结合业务日志快速定位错误信息。
  2. 可视化: 各个阶段耗时,进行性能分析。
  3. 依赖优化:各个调用环节的可用性、梳理服务依赖关系以及优化。
  4. 数据分析,优化链路:可以得到用户的行为路径,汇总分析应用在很多业务场景。

当然这些要求可能有些过分了,但我们换着自己的目标进行技术选型。

接下来我们主要来介绍四种常见的开源链式追踪系统,除了一些背景、所使用技术栈、支持的技术栈,我们还需要深入代码层面进行分析等等

了解链式追踪系统

cat, zipkin, pinpoint , skywalking

cat

由大众点评开源,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控 。 集成方案是通过代码埋点的方式来实现监控,比如: 拦截器,注解,过滤器等。 对代码的侵入性很大,集成成本较高。风险较大。

支持技术栈:

  • dubbo
  • spring mvc ,spring aop ,springmvc-url
  • spring boot
  • mybatis
  • log4j , logback
  • playframework
  • http请求

zipkin

由Twitter团队开源, Zipkin是一个分布式的跟踪系统。它有助于收集数据需要解决潜在的问题在市微服架构的时机。它管理数据的收集和查找 。

该产品结合spring-cloud-sleuth使用较为简单, 集成很方便。 但是功能较简单。

支持技术栈:

  • spring cloud

​ 以上是结合spring-cloud-sleuth支持的技术栈

pinpoint

由韩国团队naver团队开源,针对大规模分布式系统用链路监控,使用java写的工具。灵感来自短小精悍,帮助分析系统的

体结构和内部组件如何被调用在分布式应用提供了一个很好的解决方案。

使用java探针字节码增加技术,实现对整个应用的监控 。 对应用零侵入

支持技术栈:

  • Tomcat 6+, Jetty 8/9, JBoss 6, Resin 4, Websphere 6+, Vertx 3.3+
  • Spring, Spring Boot (Embedded Tomcat, Jetty)
  • HTTP Client 3.x/4.x, HttpConnector, GoogleHttpClient, OkHttpClient, NingAsyncHttpClient
  • Thrift, Dubbo
  • mysql, oracle, mssql, cubrid,PostgreSQL, maria
  • arcus, memcached, redis, cassandra
  • MyBatis
  • DBCP, DBCP2, HIKARICP
  • gson, Jackson, Json Lib
  • log4j, Logback

skywalking

2015年由个人吴晟(华为开发者)开源 , 2017年加入Apache孵化器。

针对分布式系统的应用性能监控系统,特别针对微服务、cloud native和容器化(Docker, Kubernetes, Mesos)架构, 其核心是个分布式追踪系统。

使用java探针字节码增加技术,实现对整个应用的监控 。 对应用零侵入

支持技术栈

  • Tomcat7+ , resin3+, jetty
  • spring boot ,spring mvc
  • strtuts2
  • spring RestTemplete ,spring-cloud-feign
  • okhttp , httpClient
  • msyql ,oracle , H2 , sharding-jdbc,PostgreSQL
  • dubbo,dubbox ,motan, gRpc ,
  • rocketMq , kafla
  • redis, mongoDB,memcached ,
  • elastic-job , Netflix Eureka , Hystric


深入分析技术目标要求

该小节文字摘自:https://juejin.im/post/5a7a9e0af265da4e914b46f1

我们选择全链路监控组件有哪些目标要求呢?在谷歌论文《 Dapper,大规模分布式系统的跟踪系统》,总结如下:

1、探针的性能消耗

APM组件服务的影响应该做到足够小。服务调用埋点本身会带来性能损耗,这就需要调用跟踪的低损耗,实际中还会通过配置采样率的方式,选择一部分请求去分析请求路径。在一些高度优化过的服务,即使一点点损耗也会很容易察觉到,而且有可能迫使在线服务的部署团队不得不将跟踪系统关停。

2、代码的侵入性

即也作为业务组件,应当尽可能少入侵或者无入侵其他业务系统,对于使用方透明,减少开发人员的负担

对于应用的程序员来说,是不需要知道有跟踪系统这回事的。如果一个跟踪系统想生效,就必须需要依赖应用的开发者主动配合,那么这个跟踪系统也太脆弱了,往往由于跟踪系统在应用中植入代码的bug或疏忽导致应用出问题,这样才是无法满足对跟踪系统“无所不在的部署”这个需求。

3、可扩展性

一个优秀的调用跟踪系统必须支持分布式部署,具备良好的可扩展性。能够支持的组件越多当然越好。或者提供便捷的插件开发API,对于一些没有监控到的组件,应用开发者也可以自行扩展。

4、数据的分析

数据的分析要快 ,分析的维度尽可能多。跟踪系统能提供足够快的信息反馈,就可以对生产环境下的异常状况做出快速反应。分析的全面,能够避免二次开发


功能要求

1、埋点与生成日志

埋点即系统在当前节点的上下文信息,可以分为 客户端埋点、服务端埋点,以及客户端和服务端双向型埋点。埋点日志通常要包含以下内容traceId、spanId、调用的开始时间,协议类型、调用方ip和端口,请求的服务名、调用耗时,调用结果,异常信息等,同时预留可扩展字段,为下一步扩展做准备;

不能造成性能负担:一个价值未被验证,却会影响性能的东西,是很难在公司推广的!

因为要写log,业务QPS越高,性能影响越重。通过采样和异步log解决

2、收集和存储日志

主要支持分布式日志采集的方案,同时增加MQ作为缓冲;

  1. 每个机器上有一个 deamon 做日志收集,业务进程把自己的Trace发到daemon,daemon把收集Trace往上一级发送;
  2. 多级的collector,类似pub/sub架构,可以负载均衡;
  3. 对聚合的数据进行 实时分析和离线存储
  4. 离线分析 需要将同一条调用链的日志汇总在一起;

3、分析和统计调用链路数据,以及时效性

调用链跟踪分析:把同一TraceID的Span收集起来,按时间排序就是timeline。把ParentID串起来就是调用栈

抛异常或者超时,在日志里打印TraceID。利用TraceID查询调用链情况,定位问题。

依赖度量

  1. 强依赖:调用失败会直接中断主流程
  2. 高度依赖:一次链路中调用某个依赖的几率高
  3. 频繁依赖:一次链路调用同一个依赖的次数多

离线分析:按TraceID汇总,通过Span的ID和ParentID还原调用关系,分析链路形态。

实时分析:对单条日志直接分析,不做汇总,重组。得到当前QPS,延迟。

4、展现以及决策支持


四种系统对比

模拟了三种并发用户:500,750,1000。使用jmeter测试,每个线程发送30个请求,设置思考时间为10ms。使用的采样率为1,即100%,这边与生产可能有差别。

pinpoint默认的采样率为20,即50%,通过设置agent的配置文件改为100%。zipkin默认也是1。组合起来,一共有12种。下面看下汇总表:

http://wiki.enmonster.com/download/attachments/8886428/1525326931.jpgversion=1&modificationDate=1525326944536&api=v2

在三种链路监控组件中,skywalking的探针对吞吐量的影响最小,zipkin的吞吐量居中。pinpoint的探针对吞吐量的影响较为明显

在500并发用户时,测试服务的吞吐量从1385降低到774,影响很大。然后再看下CPU和memory的影响,在内部服务器进行的压测,对CPU和memory的影响都差不多在10%之内。

比较

比较 cat zipkin pinpoint skywalking
依赖 Java 6,7,8Maven 3.2.3+mysql5.6Linux 2.6以及之上(2.6内核才可以支持epoll) Java 6,7,8Maven3.2+rabbitMQ Java 6,7,8maven3+Hbase0.94+ Java 6,7,8maven3.0+nodejszookeeperelasticsearch
实现方式 代码埋点(拦截器,注解,过滤器等) 拦截请求,发送(HTTP,mq)数据至zipkin服务 java探针,字节码增强 java探针,字节码增强
存储选择 mysql , hdfs in-memory , mysql , Cassandra , Elasticsearch HBase elasticsearch , H2
通信方式 http , MQ thrift GRPC
MQ监控 不支持 不支持 不支持 支持(RocketMQ,kafka)
全局调用统计 支持 不支持 支持 支持
trace查询 不支持 支持 不支持 支持
报警 支持 不支持 支持 支持
JVM监控 不支持 不支持 支持 支持
star数 4.5K 7.9K 5.6K 2.8K
优点 功能完善。 spring-cloud-sleuth可以很好的集成zipkin , 代码无侵入,集成非常简单 , 社区更加活跃。对外提供有query接口,更加容易二次开发 完全无侵入, 仅需修改启动方式,界面完善,功能细致。 完全无侵入,界面完善,支持应用拓扑图及单个调用链查询。功能比较完善(zipkin + pinpoint)
缺点 代码侵入性较强,需要埋点文档比较混乱,文档与发布版本的符合性较低,需要依赖点评私服 (或者需要把他私服上的jar手动下载下来,然后上传到我们的私服上去)。 默认使用的是http请求向zipkin上报信息,耗性能。跟sleuth结合可以使用rabbitMQ的方式异步来做,增加了复杂度,需要引入rabbitMQ 。数据分析比较简单。 不支持查询单个调用链, 对外表现的是整个应用的调用生态。二次开发难度较高 3.2版本之前BUG较多 ,网上反映兼容性较差 . 3.2新版本的反映情况较少依赖较多。
文档 网上资料较少,仅官网提供的文档,比较乱 文档完善 文档完善 文档完善
开发者 大众点评 twitter naver 吴晟(华为开发者) ,目前已经加入Apache孵化器
使用公司 大众点评, 携程, 陆金所,同程旅游,猎聘网 twitter naver 华为软件开发云、天源迪科、当当网、京东金融

该技术对比参考:https://blog.csdn.net/u012394095/article/details/79700200


技术源码分析

SkyWalking:http://www.iocoder.cn/categories/SkyWalking/

Zipkin:http://www.iocoder.cn/Zipkin/good-collection/


展望

由于本人接触分布式链路追踪时间不久,尚未理解它们各个的架构、网络拓扑,后续个人补上,当然有兴趣的小伙伴可以自行get。


本文章来源:https://github.com/Zeb-D/my-review

你可能感兴趣的:(分布式,分布式,中间件)