我们最近升级改造我们链路跟踪系统Log2,然后我们花了将近一周时间调研不少开源的链路跟踪系统,在此调研过程中,做了一些笔记和总结,若有误请指教。
在分布式系统架构里面,往往包含众多应用服务,这些服务之间通过RPC调用来完成业务请求,如果其中某个RPC请求异常、超时和错误,很难去定位。这时我们需要分布式链路跟踪,去跟进请求链路到底有哪些服务,请求参数、请求结果、超时异常等情况,就可以清晰可见,然后监控服务运行状况和快速定位问题。
例如:在分布式微服务系统中,一个来自用户的请求,请求先达到网关接口A,然后网关接口通过远程调用A,B服务获取结果最终,A服务调用后端算法服务C、D,算法服务D需要需要访问ES, 这样经过一系列服务调用后最后将数据返回。经历了这么多个服务,怎么样将它的请求过程的数据记录下来呢?在各种服务之间调用我们面临主要问题:
1、监控问题:如何快速发现和定位问题?即如何做好链路监控,及时掌握系统健康状况和实时了解自身的业务运行情况。
2、故障问题:如何判断故障影响范围? 某个服务出现问题后,可以判断对系统哪些服务有影响。
3、依赖问题:如何梳理服务依赖以及依赖的合理性? 服务依赖是否存在逆向或者循环调用。
4、性能分析:如何分析链路性能问题和容量规划?对于激增的流量可以有应急方案和准备。
同时我们会关注在请求处理期间各个调用的各项性能指标,比如:吞吐量(TPS)、响应时间及错误记录等。
全链路性能监控 从整体维度到局部维度展示各项指标 ,将跨应用的所有调用链性能信息集中展现,可方便度量整体和局部性能,并且方便找到故障产生的源头,生产上可极大缩短故障排除时间。
在这种情况下,一般都会引入APM(Application Performance Management & Monitoring应用性能监控管理)系统,通过各种探针采集数据,收集关键指标,同时搭配数据呈现和监控告警,能够解决上述的大部分问题。
Google开源的 Dapper链路追踪组件,并在2010年发表了论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》(即《 Dapper,大规模分布式系统的跟踪系统》),这篇文章是业内实现链路追踪的标杆和理论基础,具有非常大的参考价值。
Dapper 的基本思路 :是在服务调用的请求和响应中加入SpanID,标明上下游请求的关系。利用这些跟踪信息,可以可视化地分析服务调用链路和服务间的依赖关系。
《 Dapper,大规模分布式系统的跟踪系统》,总结如下:
埋点即系统在当前节点的上下文信息,可以分为 客户端埋点、服务端埋点,以及客户端和服务端双向型埋点。埋点日志通常要包含以下内容traceId、spanId、调用的开始时间,协议类型、调用方ip和端口,请求的服务名、调用耗时,调用结果,异常信息等,同时预留可扩展字段,为下一步扩展做准备;
不能造成性能负担:一个价值未被验证,却会影响性能的东西,是很难在公司推广的!
因为要写log,业务QPS越高,性能影响越重。通过采样和异步log解决。
主要支持分布式日志采集的方案,同时增加MQ作为缓冲;
每个机器上有一个 deamon 做日志收集,业务进程把自己的Trace发到daemon,daemon把收集Trace往上一级发送;
多级的collector,类似pub/sub架构,可以负载均衡;
对聚合的数据进行 实时分析和离线存储;
离线分析 需要将同一条调用链的日志汇总在一起;
调用链跟踪分析:把同一TraceID的Span收集起来,按时间排序就是timeline。把ParentID串起来就是调用栈。
抛异常或者超时,在日志里打印TraceID。利用TraceID查询调用链情况,定位问题。
离线分析:按TraceID汇总,通过Span的ID和ParentID还原调用关系,分析链路形态。
实时分析:对单条日志直接分析,不做汇总,重组。得到当前QPS,延迟。
APM组件服务的影响应该做到足够小。服务调用埋点本身会带来性能损耗,这就需要调用跟踪的低损耗,实际中还会通过配置采样率的方式,选择一部分请求去分析请求路径。在一些高度优化过的服务,即使一点点损耗也会很容易察觉到,而且有可能迫使在线服务的部署团队不得不将跟踪系统关停。
即也作为业务组件,应当尽可能少入侵或者无入侵其他业务系统,对于使用方透明,减少开发人员的负担。
对于应用的程序员来说,是不需要知道有跟踪系统这回事的。如果一个跟踪系统想生效,就必须需要依赖应用的开发者主动配合,那么这个跟踪系统也太脆弱了,往往由于跟踪系统在应用中植入代码的bug或疏忽导致应用出问题,这样才是无法满足对跟踪系统“无所不在的部署”这个需求。
一个优秀的调用跟踪系统必须支持分布式部署,具备良好的可扩展性。能够支持的组件越多当然越好。或者提供便捷的插件开发API,对于一些没有监控到的组件,应用开发者也可以自行扩展。
数据的分析要快 ,分析的维度尽可能多。跟踪系统能提供足够快的信息反馈,就可以对生产环境下的异常状况做出快速反应。分析的全面,能够避免二次开发。
在谷歌论文《 Dapper,大规模分布式系统的跟踪系统》的指导下,许多优秀开源的APM系统应运而生。
目前市面上开源的APM系统主要有CAT、Zipkin、Pinpoint、SkyWalking,大都是参考Google的 Dapper 实现。
CAT:是由国内美团点评开源的,基于Java语言开发,目前提供Java、C/C++、Node.js、Python、Go等语言的客户端,监控数据会全量统计,国内很多公司在用,例如美团点评、携程、拼多多等。从网上相关资源查阅:集成方案是通过代码埋点的方式来实现监控,比如: 拦截器,注解,过滤器等。 对代码的侵入性很大,集成成本较高。风险较大。
Zipkin:由Twitter公司开发并开源,Java语言实现。如果是基于spring cloud 微服务系统,结合spring-cloud-sleuth使用较为简单, 集成很方便。
Pinpoint:一个韩国团队开源的产品,运用了字节码增强技术,只需要在启动时添加启动参数即可,对代码 无侵入 ,目前支持Java和PHP语言,底层采用HBase来存储数据,探针收集的数据粒度非常细,但性能损耗大,因其出现的时间较长,完成度也很高,应用的公司较多
SkyWalking: 国人开源的产品,主要开发人员来自于华为 ,2019年4月17日Apache董事会批准SkyWalking成为顶级项目,支持Java、.Net、NodeJs等探针,数据存储支持Mysql、Elasticsearch等,跟Pinpoint一样采用字节码注入的方式实现代码的 无侵入 ,探针采集数据粒度粗,但性能表现优秀,且对云原生支持,目前增长势头强劲,社区活跃,中文文档没有语言障碍
面对各种链式追踪系统开源,我们如何选择:
1、结合公司自身情况:包括系统复杂度、使用技术栈。
2、根据上面提到APM的技术需求:探针的性能消耗、代码的侵入性、可扩展性、数据分析的指标来选择。
cat | zipkin | pinpoint | skywalking | |
---|---|---|---|---|
依赖 | Java 6,7,8 Maven 3.2.3+ mysql5.6 Linux 2.6以及之上(2.6内核才可以支持epoll) |
Java 6,7,8 Maven3.2+ rabbitMQ |
Java 6,7,8 maven3+ Hbase0.94+ |
Java 6,7,8 maven3.0+ nodejs zookeeper elasticsearch |
实现方式 | 代码埋点(拦截器,注解,过滤器等) | 拦截请求,发送(HTTP,mq)数据至zipkin服务 | java探针,字节码增强 | java探针,字节码增强 |
存储选择 | mysql , hdfs | in-memory , mysql , Cassandra , Elasticsearch | HBase | elasticsearch , mysql、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) |
缺点 | 1、代码侵入性较强,需要埋点 2、文档比较混乱,文档与发布版本的符合性较低,需要依赖点评私服 (或者需要把他私服上的jar手动下载下来,然后上传到我们的私服上去)。 |
1、默认使用的是http请求向zipkin上报信息,耗性能。 2、跟sleuth结合可以使用rabbitMQ的方式异步来做,增加了复杂度,需要引入rabbitMQ 。 3、数据分析比较简单。 |
1、不支持查询单个调用链, 对外表现的是整个应用的调用生态。 2、二次开发难度较高 |
1、3.2版本之前BUG较多 ,网上反映兼容性较差 . 3.2新版本的反映情况较少 2、依赖较多。 |
文档 | 网上资料较少,仅官网提供的文档,比较乱 | 文档完善 | 文档完善 | 文档完善 |
开发者 | 大众点评 | naver | 吴晟(华为开发者) ,目前已经加入Apache孵化器 | |
支持技术栈 | dubbo spring mvc ,spring aop ,springmvc-url spring boot mybatis log4j , logback playframework http请求 |
dubbo spring mvc spring boot |
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 |
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 |
使用公司 | 大众点评, 携程, 陆金所,同程旅游,猎聘网 | naver | 华为软件开发云、天源迪科、当当网、京东金融 | |
客户端支持语言 | JavaScript,Python,Java, Scala, Ruby, C#, Go | Java,.NETCore ,PHP, Python和 NodeJS |
我们没有实际测试这些组件的性能:摘自 https://juejin.im/post/5a7a9e0af265da4e914b46f1
比较关注探针的性能,毕竟APM定位还是工具,如果启用了链路监控组建后,直接导致吞吐量降低过半,那也是不能接受的。对skywalking、zipkin、pinpoint进行了压测,并与基线(未使用探针)的情况进行了对比。
选用了一个常见的基于Spring的应用程序,他包含Spring Boot, Spring MVC,redis客户端,mysql。 监控这个应用程序,每个trace,探针会抓取5个span(1 Tomcat, 1 SpringMVC, 2 Jedis, 1 Mysql)。这边基本和 skywalkingtest 的测试应用差不多。
模拟了三种并发用户:500,750,1000。使用jmeter测试,每个线程发送30个请求,设置思考时间为10ms。使用的采样率为1,即100%,这边与生产可能有差别。pinpoint默认的采样率为20,即50%,通过设置agent的配置文件改为100%。zipkin默认也是1。组合起来,一共有12种。下面看下汇总表:
从上表可以看出,在三种链路监控组件中, skywalking的探针对吞吐量的影响最小,zipkin的吞吐量居中。pinpoint的探针对吞吐量的影响较为明显 ,在500并发用户时,测试服务的吞吐量从1385降低到774,影响很大。然后再看下CPU和memory的影响,在内部服务器进行的压测,对CPU和memory的影响都差不多在10%之内。
开发zipkin-Server(其实就是提供的开箱即用包),zipkin-agent与zipkin-Server通过http或者mq进行通信, http通信会对正常的访问造成影响,所以还是推荐基于mq异步方式通信 ,zipkin-Server通过订阅具体的topic进行消费。这个当然是可以扩展的, 多个zipkin-Server实例进行异步消费mq中的监控信息 。
skywalking的collector支持两种部署方式: 单机和集群模式。collector与agent之间的通信使用了gRPC 。
同样,pinpoint也是支持集群和单机部署的。 pinpoint agent通过thrift通信框架,发送链路信息到collector 。
===================================================================
参考: https://juejin.im/post/5a7a9e0af265da4e914b46f1