Spring Cloud Alibaba实践——调用链监控Sleuth

需求和背景

在微服务场景下,应用被拆分成多个微服务,并互相调用,在这种情况下,跨微服务的API调用发生异常或者发生性能瓶颈时,需要快速定位并解决问题。这时可以使用调用链监控工具来监控微服务调用链的实时情况。

调用链监控原理

以之前内容中心里的/shares/{id}接口调用用户中心/users/{id}接口查询投稿人的信息为例:

  1. 客户端发送(Client Send)--CS

    表示内容中心向用户中心发送请求。

  2. 服务端接收(Server Receive)--SR

    表示用户中心接收到请求。

  3. 服务端响应(Server Send)——SS

    表示用户中心接收到请求并处理完成后响应内容中心

  4. 客户端接收(Client Receive)--CR

    表示内容中心接收到用户中心的响应。

其中这四个阶段包括三个过程。第一个过程是CS-SR,这个过程表示从客户端发送请求开始,到服务端接收请求后的网络通讯时间。第二个过程是SR-SS,这个过程表示从服务端接收到请求开始,到服务端执行请求结束时的处理时间。第三个过程是SS-CR,这个过程表示从服务端发起响应请求开始,到客户端接收到响应结束时的网络通讯时间。

通过记录这三个过程的持续时间,即可实现对调用链的监控。

整合Sleuth

Sleuth是一个Spring Cloud的分布式跟踪解决方案。

Sleuth术语

  1. Span(跨度) Sleuth的基本工作单元,它用一个64位的id唯一标识。除ID外,span还包含其他数据,例如描述、时间戳事件、键值对的注解(标签)、span IDspan父ID等。

    Span对应上面的调用链监控原理里的四阶段中的某一阶段。

  2. trace(跟踪)

    一组span组成的树状结构称为trace

    trace对应一个调用链的多个执行步骤的详细信息。

  3. Annotation(标注)

    • CS(Client Sent 客户端发送):客户端发起一个请求,该annotation描述了span的开始。
    • SR(Server Received服务器端接收):服务器端获得请求并准备处理它。
    • SS(Server Sent服务器端发送):该annotation表明完成请求处理(当响应发回客户端时)。
    • CR(Client Received客户端接收)span结束的标识。客户端成功接收到服务器端的响应。

为用户中心整合Sleuth

首先添加Sleuth的依赖:

1
2
3
4
5
6
7
<!-- 添加Spring Cloud  sleuth依赖 -->
<!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-sleuth -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
    <version>2.2.7.RELEASE</version>
</dependency>

可在配置项中配置Sleuth的相关日志打印信息:

1
2
3
logging:
  level:
    org.springframework.cloud.sleuth: debug

启动用户中心后,访问127.0.0.1:8081/users/1,不添加X-Token可以看到后台打印出了对应的Sleuth的日志信息,包含应用名称traceIdspanId是否将信息传递到Zipkin等信息。

但是,这种日志信息不方便查看,不利于快速定位问题,所以需要引入Zipkin客户端来更方便的查看调用链监控信息。

Zipkin搭建与整合

ZipkinTwitter开源的分布式追踪系统,主要用来收集系统的时序数据,从而追踪系统的调用问题。

访问如下地址下载最新Zipkin控制台程序:

1
https://search.maven.org/remote_content?g=io.zipkin&a=zipkin-server&v=LATEST&c=exec

使用jar -jar 命令运行下载下来的jar包即可。

然后在用户中心中添加Zipkin的依赖:

1
2
3
4
5
6
<!-- 添加Spring zipkin依赖,其中已包含sleuth -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
    <version>2.2.7.RELEASE</version>
</dependency>

因为Zipkin的依赖项中已经包含了Sleuth了,所以之前的Sleuth的依赖项可以去除掉。

然后添加Zipkin的配置信息:

1
2
3
4
5
6
7
spring:
  zipkin:
    base-url: http://localhost:9411/
  sleuth:
    sampler:
      # 抽样率,默认是0.1(10%)
      probability: 1.0

抽样率设置为1.0表示将把全部的调用信息都上传到Zipkin客户端上,以便测试使用。

启动用户中心,访问两次127.0.0.1:8081/users/1接口,一次带X-Token参数,一次不带X-Token参数,然后访问http://127.0.0.1:9411/zipkin/,选择serviceName用户中心,查询可以看到刚才的两次调用记录,一次成功,一次失败,查看详情可以看到详细HTTP信息以及对应的执行时间信息。同时Zipkin控制台还支持丰富的按条件查询的功能,可以很方便地查询监控数据。

为所有微服务整合Zipkin

将前面为内容中心整合Zipkin的相关代码添加到Gateway用户中心里,并配置好Gateway网关到用户中心内容中心的映射,如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
spring:
  cloud:
    gateway:
      routes:
        - id: user_route
          uri: lb://user-center
          predicates:
            - TimeBetween=上午0:00,下午11:59
            # 配置Gateway要映射到用户中心的uri的地址前缀
            - Path=/users/**
          # 添加一个向发往用户中心的请求上添加Header项的拦截器
          filters:
            - AddRequestHeader=X-Request-Foo, Bar
            - PreLog=a,b
        - id: content_route
          uri: lb://content-center
          predicates:
            - TimeBetween=上午0:00,下午11:59
            # 配置Gateway要映射到内容中心的uri的地址前缀
            - Path=/shares/**,/admin/**
          # 添加一个向发往内容中心的请求上添加Header项的拦截器
          filters:
            - AddRequestHeader=X-Request-Foo, Bar
            - PreLog=a,b

然后启动三个微服务,访问127.0.0.1:8040/shares/1?origin=browser两次,一次带X-Token,一次不带。因为这个接口的调用路径是Gateway->content-center->user-center,所以此时访问http://127.0.0.1:9411/zipkin,选择serviceNamegateway的服务,可以查询到刚才的两次调用记录,一次成功,一次失败,点击成功的那条记录查看详情,可以看到调用链路上的每一次记录,及每一个节点的开始时间,可以很方便地分析微服务之间的调用链信息及相关性能瓶颈等问题。

Zipkin持久化

默认情况下Zipkin里的调用链监控记录是保存在内存中的,在生产环境需要对其进行持久化,可以将其保存在MySQLElasticSearchCassandra等工具中。MySQL存储方案,当数据量较大时,会出现性能问题,会需要秒级才能查询到数据的情况。

相关文档:https://github.com/openzipkin/zipkin#storage-component