微服务系统追踪微服务调用,跟踪记录一次用户请求经过哪些调用,经过哪些服务处理,并且记录每一次调用所设计的服务的详细信息。如果发生调用失败,可以根据日志快速定位出现问题的环节。

一、作用

     1.优化系统瓶颈

         通过记录调用经过的每一条链路上的耗时,快速定位系统中的瓶颈点。

      2.优化链路调用

         通过服务追钟可以分析调用所经过的路径,然后评估是否合理,通过对调用链路进行分析,可以跨数据中心的服务调用,从而进行优化,尽量规避这种情况。

      3.生成网络拓扑

          通过服务追踪系统中记录的链路信息,可以生成一张系统的网络调用拓扑图,它可以反映系统都依赖了哪些服务,以及服务之间的调用关系是什么样的,在网络拓扑图上还可以把服务调用的详细信息也标出来,也能起到服务监控的作用。

      4.透明传输数据

二、原理

       核心原理就是调用链,通过一个全局唯一的ID将分布在各个服务节点上的同一次请求串联起来,从而还原原有的调用关系,可以追钟系统问题、分析调用数据并统计各个系统指标。

       Google的Dapper详细的实现原理,大规模分布式系统的跟踪系统http://bigbully.github.io/Dapper-translation/

微服务调用 微服务调用链路_数据

  • traceId,用于标识某一次具体的请求 ID。当用户的请求进入系统后,会在 RPC 调用网络的第一层生成一个全局唯一的 traceId,并且会随着每一层的 RPC 调用,不断往后传递,这样的话通过 traceId 就可以把一次用户请求在系统中调用的路径串联起来。
  • spanId,用于标识一次 RPC 调用在分布式请求中的位置。当用户的请求进入系统后,处在 RPC 调用网络的第一层 A 时 spanId 初始值是 0,进入下一层 RPC 调用 B 的时候spanId 是 0.1,继续进入下一层 RPC 调用 C 时 spanId 是 0.1.1,而与 B 处在同一层的RPC 调用 E 的 spanId 是 0.2,这样的话通过 spanId 就可以定位某一次 RPC 请求在系统调用中所处的位置,以及它的上下游依赖分别是谁。
  • annotation,用于业务自定义埋点数据,可以是业务感兴趣的想上传到后端的数据,比如一次请求的用户 UID。

       traceId 是用于串联某一次请求在系统中经过的所有路径,spanId 是用于区分系统不同服务之间调用的先后关系,而 annotation 是用于业务自定义一些自己感兴趣的数据,在上传 traceId 和 spanId 这些基本信息之外,添加一些自己感兴趣的信息。

三、实现

微服务调用 微服务调用链路_链路_02

  • 数据采集层:负责数据埋点并上报,在系统的各个模块中进行埋点,采集数据并上报给数据处理层进行处理。

        

微服务调用 微服务调用链路_链路_03

负责数据存储与计以红色方框里圈出的 A 调用 B 的过程为例,一次 RPC 请求可以分为四个阶段。
CS(Client Send)阶段 : 客户端发起请求,并生成调用的上下文。
SR(Server Recieve)阶段 : 服务端接收请求,并生成上下文。
SS(Server Send)阶段 : 服务端返回请求,这个阶段会将服务端上下文数据上报,下面
这张图可以说明上报的数据有:traceId=123456,spanId=0.1,appKey=B,
method=B.method,start=103,duration=38。
CR(Client Recieve)阶段 : 客户端接收返回结果,这个阶段会将客户端上下文数据上
报,上报的数据有:traceid=123456,spanId=0.1,appKey=A,
method=B.method,start=103,duration=38。

微服务调用 微服务调用链路_数据_04

  • 数据处理层:负责数据的存储与计算,,把数据采集层上报的数据按需计算,然后落地存储供查询使用。

        数据处理得需求分为两类:实时计算需求和离线计算需求,实时计算需求对计算效率要求比较高,一般要求对收集的链路数据能够在秒级别完成聚合计算,以供实时查询。而离线计算需求对计算效率要求就没那么高了,一般能在小时级别完成链路数据的聚合计算即可,一般用作数据汇总统计。

        实时数据处理:

       针对实时数据处理,一般采用 Storm 或者 Spark Streaming 来对链路数据进行实时聚合加工,存储一般使用 OLTP 数据仓库,比如 HBase,使用 traceId 作为 RowKey,能天然地把一整条调用链聚合在一起,提高查询效率。

       离线数据处理:

       针对离线数据处理,一般通过运行 MapReduce 或者 Spark 批处理程序来对链路数据进行离线计算,存储一般使用 Hive。

  • 数据展示层:负责数据的图形化展示,将处理后的链路信息以图形化的方式展示给用户。

        主要展示两种图形:调用链路图和调用拓扑图