求取一份极致的简单:全链路跟踪中间件探索之路

公司内部的业务系统有近千个,基本上很少有比较孤立的;尤其外部系统,即便用户在页面上一个很普通的操作,后台也需要少则几个多则几十个服务协同完成。以前我们定位调用链上的问题方式,基本上都是叫上调用链上所有对服务比较熟悉的技术人员,定位问题费时费力;由此,我们团队决定引入一套全链路跟踪中间件产品。

起初,我们全面调研了社区很多比较成熟的产品之后,发现这些产品与我们公司现存场景多有不符的地方,主要的一点就是我们公司内部应用之间通信方式的多样化。各业务部门之间技术栈极不统一,各业务部门内部的应用之间以及各业务部门应用之间的通信方式自然也多种多样,公开服务的方式包括:REST、RabbitMQ、Dubbo、RMI、Zookeeper等,调用服务的方式包括:OkHttp 2.x、OkHttp 3.x 、Apache HttpClient、Spring RestTemplate、RabbitMQ、Dubbo、RMI、Zookeeper等。我们在自研这套产品过程中,首先参考了谷歌公开的《Dapper大规模分布式系统的跟踪系统》这篇论文,借鉴了社区类似产品的很多思路和理念,像Twitter的Zipkin、阿里的鹰眼、去哪儿网的QTracer、GitHub上开源的PinPoint等产品。

一. 设计目标

设计目标是企业的设计部门根据设计战略的要求组织各项设计活动预期取得的成果。在产品设计之初,我们就参考了谷歌公开的《Dapper大规模分布式系统的跟踪系统》论文及我们的实际业务场景,制定了如下设计目标:

  • 低消耗:全链路跟踪中间件在接入后应该做到对在线服务的影响足够小,甚至可以忽略不计;
  • 低侵入:不应该让各在线服务显示感受到跟踪API的存在,至少不应该显示侵入业务代码内部,也就是不能出现在类中的import处;
  • 可开关:全链路跟踪中间件的调用链参数传递及日志落地时机要做到在线开关,以避免重大Bug影响在线服务;
  • 延展性:全链路跟踪中间件至少在未来几年的服务体量和集群规模都应该能完全把控住,主要针对的是存储组件。

二. 产品架构

Trace Agent:各业务服务内部的埋点,其中包括各种通信方式的参数传递、配置模块、接入模块等,最终将调用链节点数据以日志形式落地;

Filebeat:采集Trace agent产生的调用链节点日志并送给Logstash;

Logstash:对跟踪日志进行再处理,像属性提取并结构化后输出到ElasticSearch;

ElasticSearch:调用链节点日志的最终存储地,每个节点日志以行为单位进行存储;

Trace Web UI:数据展现页分为四部分,调用链TraceId列表、调用链列表、依赖分析图(基于百度的Echarts)、节点详情页,如下:

  • 调用链TraceId列表
  • 调用链列表
  • 依赖分析图
  • 节点详情页

三. 追本溯源

全链路跟踪中间件产品要解决的第一个非常重要的问题就是调用链源头的追溯,随着对产品的理解逐渐加深,关于调用链源头我们梳理出两点,一是人为调用(触发页面上某事件),二是系统定时调用(定时任务触发):

  • 人为调用:调用链源头可追溯至javax.servlet.Filter上
  • 系统定时调用:调用链源头可追溯至定时任务的执行点(基于我们自研的分布式定时任务产品)

四. 传递之道

全链路跟踪中间件产品要解决的第二个非常重要的问题就是调用链参数(traceId和父spanId)向下游服务传递。在调用下游服务时,有些调用是不需要跟踪的,比如调用Kubernetes的REST接口、ES的REST接口,所以我们设计了三级开关处理:机器级开关(跳掉某个IP的跟踪)、应用级开关(跳掉某个应用的跟踪)、接口级开关(跳掉应用内某个接口的跟踪)。各种通信方式调用链参数传递逻辑如下:

  • OkHttp2.x、OkHttp3.x(HTTP)
  • Apache HttpClient(HTTP)
  • Spring RestTemplate(HTTP)
  • REST接口(HTTP)
  • RabbitMQ Send(MQ)
  • RabbitMQ Recv(MQ)
  • Dubbo Provider(RPC)
  • Dubbo Consumer(RPC)
  • RMI Server(RPC)
  • RMI Client(RPC)
  • 异步调用时,线程池内的线程是获取不到与主线程关联的对象数据的,需要用使用阿里开源的一个类库(transmittable-thread-local)对原有线程池进行包装:

五. 落地之机

全链路跟踪中间件产品要解决的第三个非常重要的问题就是调用链节点日志的落地时机,客户端在某个调用的点进行落地(防止多点重复落地),而服务端在响应点逻辑执行完进行落地。各种通信方式调用链节点日志落地逻辑如下:

  • OkHttp2.x、OkHttp3.x(HTTP)
  • Apache HttpClient(HTTP)
  • Spring RestTemplate(HTTP)
  • REST接口(HTTP)
  • RabbitMQ Send(MQ)
  • RabbitMQ Recv(MQ)
  • Dubbo(RPC)
  • RMI Server(RPC)

六. 改造之旅

在产品设计之初,我们就将“低侵入”作为一个明确的设计目标,产品最终做到了隐式侵入,也就是在产品上线之后,要求业务系统重新发布即可,无需任何业务代码上的改动(OkHttp3、Apache HttpClient、Dubbo使用方式需调整)。

  • BeanPostProcessor(Spring的扩展点实现隐式改造)
  • OkHttp3注册方式调整(OkHttp3的拦截器链List是不可能更改的):
  • Apached HttpClient注册方式调整(Apached HttpClient的拦截器链没有公开添加的方法):
  • Dubbo服务改造(Dubbo的Filter接口没有纳入Spring体系)

Q&A

Q:这种链路追踪好像没有深入到访问数据库层,以及某个方法执行的时间和方法内部之间调用的关系吧?另外在Web上是怎么展示链路的呢?我看到有SpanId、TraceId这些都是写到log,然后用ES查询出来,再根据时间判断整个链路条,再显示在Web页面么?

A:暂时没有到数据访问层,后期我们会考虑加进去的;Web上的展示分享的内容里面有,我们是基于百度的Echarts;ES存储的数据是一个节点一条数据,然后将查出来的数据构造成多叉树使用百度的Echarts进行数据展现。

Q:TraceId生成算法,如何避免重复?

A:TraceId的生成我们融入了业务语义,业务描述部分+System.nanoTimes,业务语义部分存储在ZK中,是动态可配置的。

Q:会不会将历史数据也查出来?有区分么?

A:TraceId列表是按环境、应用、TraceId模糊查询、接口名、时间段查出来的。

原文发布于微信公众号 - Golang语言社区(Golangweb)

原文发表时间:2018-07-11

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大内老A

WCF技术剖析(卷1)之前言

第一次邂逅WCF是在微软举办的一场关于Windows Vista技术推广培训上,时间大概是2005年10月份,当时对WCF可谓是一见钟情。如果读者也像我一样,之...

1869
来自专栏北京马哥教育

25台服务器怎样支撑世界第54大网站

摘要:同时使用Linux和Windows平台产品,大量使用静态的方法和类,Stack Overflow是个重度性能控。同时,取代横向扩展,他们坚持着纵向扩展思路...

6699
来自专栏java一日一条

13个不容错过的Java项目

GitHub可谓一座程序开发的大宝库,有些素材值得fork,有些则能帮助我们改进自有代码或者学习编程技能。无论如何,开发工作当中我们几乎不可能绕得开GitHub...

4981
来自专栏魏琼东

AgileEAS.NET平台开发实例-药店系统-快速的SAAS开发体验

一、AgileEAS.NET应用开发简介 在4月份,callhot写过一系列的有关于AgileEAS.NET平台的开发应用的系列AgileEAS.NET平台开发...

2516
来自专栏WeTest质量开放平台团队的专栏

5天2亿活跃用户,2017QQ“LBS+AR”天降红包活动后台揭密

作者王家彬,腾讯后台开发工程师,参与“LBS+AR”天降红包项目,其所在“2016春节红包联合项目团队”获得2016公司级业务突破奖。

1573
来自专栏逸鹏说道

.NET技术+25台服务器怎样支撑世界第54大网站

英文原文:StackOverflow Update: 560M Pageviews A Month, 25 Servers, And It's All Abou...

3827
来自专栏vue+shiro

基于vue(element ui) + ssm + shiro 的权限框架

现在的Java世界,各种资源很丰富,不得不说,从分布式,服务化,orm,再到前端控制,权限等等玲琅满目,网上有句话说,语言框架迭代太快了,我学不动了,不如回去搬...

8612
来自专栏阮一峰的网络日志

谈谈MVC模式

1. 如何设计一个程序的结构,这是一门专门的学问,叫做"架构模式"(architectural pattern),属于编程的方法论。 MVC模式就是架构模式的一...

3125
来自专栏Seebug漏洞平台

Sebug 大牛支招之我是如何在Sebug中杀入前10的?

大家好我是koshell,ID:k0sh1, 在之前的文章中我分享了在web漏洞挖掘中的一些小技巧,这里要补充一下。 注入其实只是众多web入侵手段中的一种,脱...

3767
来自专栏java学习

电商中常见的高并发怎么处理?

在过去的工作中,我曾经面对过5w每秒的高并发秒杀功能,在这个过程中,整个Web系统遇到了很多的问题和挑战。如果Web系统不做针对性的优化,会轻而易举地陷入到异常...

2382

扫码关注云+社区

领取腾讯云代金券