分布式跟踪调研与设计

背景

公司业务由数以百计的分布式服务沟通,每个请求路由过来后,会通过多个业务系统并留下足迹,并产生对各类缓存或者DB的访问,可是这些分散的数据对于问题排查,或者流程优化比较有限。对于一个跨进程的场景,汇总收集并分析海量日志就显得尤其重要。在这种架构下,跨进程的业务流会通过不少个微服务的处理和传递,咱们不免会遇到这样的问题:html

  • 一次请求的流量从哪一个服务而来? 最终落到了哪一个服务中去?
  • 为何这个请求这么慢? 到底哪一个环节出了问题?
  • 这个操做须要依赖哪些东西? 是数据库仍是消息队列? Redis挂了,哪些业务受影响?

对于这个问题,业内已经有了一些实践和解决方案,经过调用链的方式,把一次请求调用过程完整的串联起来,这样就实现了对请求条用路径的监控。在业界,Twitter的Zipkin和淘宝的鹰眼就是相似的系统,它们都起源于Google Dapper论文,就像历史上Hadoop起源于Google Map/Reduce论文,Hbase起源于Google BigTable论文同样前端

设计目标

  • 低消耗性:跟踪系统对业务系统的影响应该作到足够小。在一些高度优化过的服务,即便一点点损耗也容易察觉到,并且有可能迫使在线负责的部署团队不得不将跟踪系统关停
  • 低侵入性:做为非业务组件,应当尽量少侵入或者无侵入业务系统,对于使用方透明,减小开发人员的负担
  • 时效性:从数据的收集产生,到数据计算处理,再到最终展示,都要求尽量快
  • 决策支持:这些数据是否能在决策支持层面发挥做用,特别是从DevOps的角度
  • 数据可视化:作到不用看日志经过可视化进行筛选

实现功能

  • 故障快速定位
    • 调用链路跟踪,一次请求的逻辑轨迹能够完整清晰的展现出来。
  • 各个调用环节的性能分析
    • 调用链的各个环节分表添加调用耗时,能够分析出系统的性能瓶颈,并针对性的优化。
  • 数据分析
    • 调用链是一条完整的业务日志,能够获得用户的行为路径,汇总分析应用在不少业务场景

设计性能指标

项目 指标
kafka > 5000 Query Per Second
数据延迟 < 1 Min
查询延迟 < 3 Second

相关软件与硬件

名称 数量 备注
Kafka 1套3节点 与监控系统共用一套集群,分属不一样Topic
ElasticSearch 1套3节点 与ELK共用一套集群,前提ELK需作扩容准备
API机器 虚拟机3台 公司标准虚拟机配置4core 8G便可

系统限制

公司服务部署在多个机房中,可是分布式跟踪的数据需汇总收集并展现,故暂时进行采用不了多机房部署方案。考虑到分布式跟踪系统相似于ELK系统的基础服务,部署架构与现有ELK保证一致,核心服务部署在B7机房git

设计思路

通常分布式跟踪系统, 主要有三个部分:数据收集,数据存储和数据展现。根据系统大小不一样,每一部分的结构又有必定变化。譬如,对于大规模分布式系统,数据存储可分为实时数据和全量数据两部分,实时数据用于故障排查,全量数据用于系统优化;数据收集除了支持平台无关和开发语言无关系统的数据收集,还包括异步数据收集(须要跟踪队列中的消息,保证调用的连贯性),以及确保更小的侵入性;数据展现又涉及到数据挖掘和分享。虽然每一部分均可能变的很复杂,但基本原理都相似。
imagegithub

图1:这个路径由用户的X请求发起,穿过一个简单的服务系统。用字母标识的节点表明分布式系统中的不一样处理过程。web

分布式服务的跟踪系统须要记录在一次特定的请求后系统中完成的全部工做的信息。举个例子,图1展示的是一个和5台服务器相关的一个服务,包括:前端(A),两个中间层(B和C),以及两个后端(D和E)。当一个用户(这个用例的发起人)发起一个请求时,首先到达前端,而后发送两个RPC到服务器B和C。B会立刻作出反应,可是C须要和后端的D和E交互以后再返还给A,由A来响应最初的请求。对于这样一个请求,简单实用的分布式跟踪的实现,就是为服务器上每一次你发送和接收动做来收集跟踪标识符(message identifiers)和时间戳(timestamped events)。数据库

黑盒和标签方案

为了将全部记录条目与发起者惯量上并记录全部信息,如今有两种解决方案,黑盒和基于标签(annotation-based)的监控方案。
黑盒方案采用framework为基础,将依赖集成进去,对各接入业务线透明。基于标签的方案,依赖业务线明确标记一个trace id,从而链接每一条记录和发起者的请求。基于标签的方案主要缺点很明显,须要植入与业务无关代码。因此默认状况下,咱们提供基于hjframework公共组件的方案,实现跟踪系统对业务无感知。同时若是须要显示使用这个标签功能的话,咱们一样提供出来,由业务方自行决定是否使用标签。后端

技术选型

公司 选项 是否开源 优缺点
淘宝 EagleEye 主要基于内部HSF实现,HSF没有开源,故鹰眼也没有开源
Twitter Zipkin 基于Http实现,支持语言较多,比较适合咱们公司业务
点评 CAT 自定义改造难度大,代码比较复杂,侵入代码,须要埋点
京东 Hydra 主要基于Dubbo实现,不适合公司Http请求为主的场景

综上所述,最终咱们以为采用Zipkin的方式来实现,比较适合公司目前以Http请求为主的场景。虽然采用第三方开源产品,可是客户端依赖的SDK,仍需咱们开发集成到HJFramewor中。针对Node和JS,Zipkin一样提供对应的前端SDK,咱们集成好以后,就能正常使用。缓存

系统设计

总体架构图及说明

基于Zipkin的基础上,咱们对其架构进行了扩展,基于Google Dapper的概念,设计一套基于Http的分布式跟踪系统。其种涵盖了信息的收集,处理和展示。
总体架构以下图所示,主要由四个部分构成:收集器、数据传输、数据存储、查询及web界面服务器

收集器

业务方之间依赖咱们提供的SDK,进行数据收集。其中SDK主要采用Spring Cloud中分布式跟踪模块是Spring Cloud Sleuth。该模块主要用于收集Spring boot系统中数据,发送至缓冲队列Kafka中。同时官方提供了针对Node、Python等一些经常使用的客户端SDK架构

数据传输

咱们在SDK与后端服务之间加了一层Kafka,这样作既能够实现两边工程的解耦,又能够实现数据的延迟消费。咱们不但愿由于瞬时QPS太高而致使数据丢失,固然为此也付出了一些实效性上的代价。

数据存储

默认存储采用ElasticSearch 来保证数据,考虑到数据量的规模,先期只保存最近1个月的数据

查询及Web界面

查询主要用来向其余服务提供数据查询的能力,而Web服务是官方默认提供的图形化界面,咱们会重写这块页面,使之与沪江内部平台结合起来。

SDK分析

调用链跟踪:把同一个TraceID和SpanID收集起来,按时间排序Timeline,把ParentID串起来就是调用栈。
image

参考资料

  • Google的大规模分布式系统的跟踪系统Dapper
  • Twitter开源的Zipkin
  • 窝窝网介绍Tracing的一篇博客
相关文章
相关标签/搜索