前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringCloud详细教程 | 第九篇:服务链路追踪(Spring Cloud Sleuth)(Greenwich版本)

SpringCloud详细教程 | 第九篇:服务链路追踪(Spring Cloud Sleuth)(Greenwich版本)

作者头像
小东啊
发布2019-06-26 15:21:14
4.2K0
发布2019-06-26 15:21:14
举报
文章被收录于专栏:李浩东的博客李浩东的博客

Spring Cloud Sleuth集成了追踪组件zipkin组件

为什么需要Spring Cloud Sleuth

微服务架构是一个分布式架构,它按业务划分服务单元,一个分布式系统往往有很多个服务单元。由于服务单元数量众多,业务的复杂性,如果出现了错误和异常,很难去定位。主要体现在,一个请求可能需要调用很多个服务,而内部服务的调用复杂性,决定了问题难以定位。所以微服务架构中,必须实现分布式链路追踪,去跟进一个请求到底有哪些服务参与,参与的顺序又是怎样的,从而达到每个请求的步骤清晰可见,出了问题,很快定位。

举个例子,在微服务系统中,一个来自用户的请求,请求先达到前端A(如前端界面),然后通过远程调用,达到系统的中间件B、C(如负载均衡、网关等),最后达到后端服务D、E,后端经过一系列的业务逻辑计算最后将数据返回给用户。对于这样一个请求,经历了这么多个服务,怎么样将它的请求过程的数据记录下来呢?这就需要用到服务链路追踪。

Google开源的 Dapper链路追踪组件,并在2010年发表了论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,这篇文章是业内实现链路追踪的标杆和理论基础,具有非常大的参考价值。目前,链路追踪组件有Google的Dapper,Twitter 的Zipkin,以及阿里的Eagleeye (鹰眼)等,它们都是非常优秀的链路追踪开源组件。

本文主要讲述如何在Spring Cloud Sleuth中集成Zipkin。在Spring Cloud Sleuth中集成Zipkin非常的简单,只需要引入相应的依赖和做相关的配置即可。

术语

Spring Cloud Sleuth借用了Dapper的术语。

  • 跨度:基本工作单元。例如,发送RPC是一个新的跨度,就像向RPC发送响应一样。跨度由跨度的唯一64位ID和跨度所属的跟踪的另一个64位ID标识。Spans还有其他数据,例如描述,带时间戳的事件,键值注释(标签),导致它们的跨度的ID以及进程ID(通常是IP地址)。 可以启动和停止跨度,并跟踪其时间信息。创建跨度后,必须在将来的某个时刻停止它。
  • 小费 启动跟踪的初始范围称为a root span。该范围的ID值等于跟踪ID。 痕迹:一组跨越形成树状结构。例如,如果运行分布式大数据存储,则可能会由PUT请求形成跟踪。
  • 注释: 用于及时记录事件的存在。使用 Brave工具,我们不再需要为Zipkin设置特殊事件,以了解客户端和服务器是谁,请求开始的位置以及结束位置。然而,出于学习目的,我们标记这些事件以突出发生了什么样的行动。
  • cs:客户已发送。客户提出了请求。此注释表示跨度的开始。
  • sr:服务器收到:服务器端获得请求并开始处理它。cs从此时间戳中减去时间戳会显示网络延迟。
  • ss:服务器已发送。在完成请求处理时(当响应被发送回客户端时)注释。sr从此时间戳中减去时间戳会显示服务器端处理请求所需的时间。
  • cr:客户收到了。表示跨度的结束。客户端已成功从服务器端收到响应。cs从此时间戳中减去时间戳会显示客户端从服务器接收响应所需的全部时间。 下图显示了Span和Trace在系统中的外观以及Zipkin注释:

Zipkin

Zipkin是一种分布式链路追踪系统。 它有助于收集解决微服务架构中的延迟问题所需的时序数据。 它管理这些数据的收集和查找。 Zipkin的设计基于Google Dapper论文。

跟踪器存在于应用程序中,记录请求调用的时间和元数据。跟踪器使用库,它们的使用对用户是无感知的。例如,Web服务器会在收到请求时和发送响应时会记录相应的时间和一些元数据。一次完整链路请求所收集的数据被称为Span。

我们可以使用它来收集各个服务器上请求链路的跟踪数据,并通过它提供的 REST API 接口来辅助我们查询跟踪数据以实现对分布式系统的监控程序,从而及时地发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发的 API 接口之外,它也提供了方便的 UI 组件来帮助我们直观的搜索跟踪信息和分析请求链路明细,比如:可以查询某段时间内各用户请求的处理时间等。Zipkin 提供了可插拔数据存储方式:In-Memory、MySql、Cassandra 以及 Elasticsearch。接下来的测试为方便直接采用 In-Memory 方式进行存储,生产推荐 Elasticsearch.

上图展示了 Zipkin 的基础架构,它主要由 4 个核心组件构成:

  • Collector:收集器组件,它主要用于处理从外部系统发送过来的跟踪信息,将这些信息转换为 - Zipkin 内部处理的 Span 格式,以支持后续的存储、分析、展示等功能
  • Storae:存储组件,它主要对处理收集器接收到的跟踪信息,默认会将这些信息存储在内存中,我们也可以修改此存储策略,通过使用其他存储组件将跟踪信息存储到数据库中。
  • RESTful API:API 组件,它主要用来提供外部访问接口。比如给客户端展示跟踪信息,或是外接系统访问以实现监控等。
  • Web UI:UI 组件,基于 API 组件实现的上层应用。通过 UI 组件用户可以方便而有直观地查询和分析跟踪信息。案例实战

本文案例一共四个工程, 都是在之前的工程上进行改造

  • eureka-server 工程,作为服务注册中心
  • zipkin-server 作为链路追踪服务中心,负责存储链路数据
  • zuul-server 作为服务网关工程,负责请求的转发,同时它也作为链路追踪客户端,负责产生数据,并上传给zipkin-service
  • eureka-client 作为一个应用服务,对外暴露API接口,同时它也作为链路追踪客户端,负责产生数据

采用官方的jar形式启动,所以需要通过下载官方的jar来启动,也通过以下命令一键启动:

curl -sSL https://zipkin.io/quickstart.sh | bash -sjava -jar zipkin.jar

上面的第一行命令会从zipkin官网下载官方的jar包。如果是window系统,建议使用gitbash执行上面的命令。

如果用 Docker 的话,使用以下命令:

docker run -d -p 9411:9411 openzipkin/zipkin

启动如下

通过java -jar zipkin.jar的方式启动之后,在浏览器上访问lcoalhost:9411,显示的界面如下:

改造eureka-client 工程

加入spring-cloud-starter-zipkin依赖

<dependency>            <groupId>org.springframework.cloud</groupId>            <artifactId>spring-cloud-starter-zipkin</artifactId>        </dependency>

修改配置文件

# 端口号server.port=8762# 需要指明spring.application.name 这个很重要# 这在以后的服务与服务之间相互调用一般都是根据这个namespring.application.name=eureka-client#服务注册中心实例的主机名eureka.instance.hostname=localhost#服务注册中心端口号eureka.port=8761#在此指定服务注册中心地址eureka.client.service-url.defaultZone=http://${eureka.instance.hostname}:${eureka.port}/eureka/
#为true设置的是web开启sleuth功能spring.sleuth.web.client.enabled=true#当设置为1.0时就是链路数据100%收集到zipkin-serverspring.sleuth.sampler.probability=1.0# 指定了 Zipkin 服务器的地址spring.zipkin.base-url=http://localhost:9411

通过引入spring-cloud-starter-zipkin依赖和设置spring.zipkin.base-url就可以了

其中

  • spring.sleuth.web.client.enable为true设置的是web开启sleuth功能
  • spring.sleuth.sampler.probability可以设置为小数,最大值为1.0,当设置为1.0时就是链路数据100%收集到zipkin-server,当设置为0.1时,即10%概率收集链路数据
  • spring.zipkin.base-url设置zipkin-server的地址。

对外暴露一个Api,方便其他服务调用

package com.li.eurekaclient;
import org.springframework.beans.factory.annotation.Value;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.cloud.netflix.eureka.EnableEurekaClient;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RequestParam;import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication@EnableEurekaClient@RestControllerpublic class EurekaClientApplication {
    public static void main(String[] args) {        SpringApplication.run(EurekaClientApplication.class, args);    }
    @Value("${server.port}")    String port;
    @RequestMapping("/hello")    public String home(@RequestParam(value = "name", defaultValue = "lhd") String name) {        return "hello: " + name + " ,from port:" + port;    }
}

然后分别在feign-server服务,zuul-server服务上加入相同依赖和配置文件即可

依次启动eureka-server, eureka-client, feign-server, zuul-server四个应用,启动完成后,打开浏览器访问http://localhost:8767/feign/hello?name=lhd&token=123 这个是网关调用feign服务的,然后feign调用client的接口,成功响应如下:

这个时候浏览器访问 http://localhost:9411/zipkin/ ,zipkin-server的页面,显示如下:

没有的话点击 Find Traces即可显示

从上图可以看出每次请求所消耗的时间,以及一些span的信息

从上图可以看出具体的服务依赖关系,zuul-server依赖了feign-server依赖了eureka-client

从上图可以看出服务之间的调用的接口以及需要的时间等等

上面的例子是将链路数据存在内存中,只要zipkin-server重启之后,之前的链路数据是全部查找不到的,zipkin是支持将链路数据存储在mysql、cassandra、elasticsearch中的。

后面会讲解如何将链路数据存储在mysql、cassandra、elasticsearch中的

源码下载: https://github.com/LiHaodong888/SpringCloudLearn

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 李浩东的博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 为什么需要Spring Cloud Sleuth
  • 术语
  • Zipkin
相关产品与服务
数据保险箱
数据保险箱(Cloud Data Coffer Service,CDCS)为您提供更高安全系数的企业核心数据存储服务。您可以通过自定义过期天数的方法删除数据,避免误删带来的损害,还可以将数据跨地域存储,防止一些不可抗因素导致的数据丢失。数据保险箱支持通过控制台、API 等多样化方式快速简单接入,实现海量数据的存储管理。您可以使用数据保险箱对文件数据进行上传、下载,最终实现数据的安全存储和提取。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档