书接上回:

SpringCloud专题之一:Eureka

Spring Cloud专题之二:OpenFeign

Spring Cloud专题之三:Hystrix

Spring Cloud 专题之四:Zuul网关

Spring Cloud专题之五:config

Spring Cloud 专题之六:bus

在一个微服务架构中,系统的规模往往会比较大,各微服务之间的调用关系也错综复杂。通常一个有客户端发起的请求在后端系统中会经过多个不同的微服务调用阿里协同产生最后的请求结果。在复杂的微服务架构中,几乎每一个前端请求都会形成一条复杂的分布式的服务调用链路,在每条链路中任何一个依赖服务出现延迟过高或错误的时候都有可能引起请求最后的失败。

这个时候,对于每个请求,全链路调用的跟踪就边得越来越重要,通过实现对请求调用的跟踪可以帮助我们快速发现问题根源以及监控分析每条请求链路上的性能瓶颈等。而Spring Cloud Sleuth就是一个提供了一套完整的解决方案的组件。

在开始今天的这个例子之前,可以看一下我之前的几篇博客,特别是hystrix之前的博客。本篇博客就是在这基础上所增加的新功能。在之前的实践中,通过9004的customer-server项目调用9003的hello-server项目的接口。

准备工作

在之前的服务调用的方法上加上日志操作。

customer-server的CustomerController类:

@RequestMapping("/sayHello1")
@ResponseBody
public String invokeSayHello1(String name){
logger.info("调用了customer-server的sayHello1方法,参数为:{}",name);
return serivce.invokeSayHello1(name);
}

hello-server的Hello1Controller类:

@RequestMapping("/sayHello1")
public String sayHello1(@RequestParam("name") String name){
logger.info("你好,服务名:{},端口为:{},接收到的参数为:{}",instanceName,host,name);
try {
int sleepTime = new Random().nextInt(3000);
logger.error("让线程阻塞 {} 毫秒",sleepTime);
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "你好,服务名:"+instanceName+",端口为:"+host+",接收到的参数为:"+name;
}

在页面上访问localhost:9004/sayHello1?name=charon

#  customer-server中的打印日志
2021-08-09 23:22:33.905 INFO 19776 --- [nio-9004-exec-8] c.c.e.controller.CustomerController : 调用了customer-server的sayHello1方法,参数为:charon # hello-server中的打印日志
2021-08-09 23:22:33.917 INFO 2884 --- [nio-9003-exec-9] c.c.e.controller.Hello1Controller : 你好,服务名:hello-server,端口为:9003,接收到的参数为:charon

实现跟踪

在修改完上面的代码后,为customer-server项目和hello-server项目添加服务跟踪的功能,引入依赖

<!--引入sleuth链路追踪的jar包-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

页面调用查看日志:

#  customer-server中的打印日志
2021-08-09 23:30:44.782 INFO [customer-server,0e307552774ef605,0e307552774ef605,true] 14616 --- [nio-9004-exec-2] c.c.e.controller.CustomerController : 调用了customer-server的sayHello1方法,参数为:charon # hello-server中的打印日志
2021-08-09 23:30:44.807 INFO [hello-server,0e307552774ef605,4cf4d9dd57ca7478,true] 6660 --- [nio-9003-exec-2] c.c.e.controller.Hello1Controller : 你好,服务名:hello-server,端口为:9003,接收到的参数为:charon

从上面的控制台的输出内容可以看到形如[customer-server,0e307552774ef605,0e307552774ef605,true] 的日志信息,而浙西而元素正是实现分布式服务跟踪的重要组成部分,每个值的含义如下:

  • customer-server:应用的名称,也就是application.properties中的soring。application.name的值
  • 0e307552774ef605:Spring Cloud Sleuth生成的一个ID,成微Trace ID,它用来标识一条请求链路,一条请求链路中包含一个Trace ID,多个Span ID。
  • 0e307552774ef605:Spring Cloud Sleuth生成的另一个ID,成为Span ID,它表识一个基本的工作单元,比如发怂一个HTTP请求
  • true:表示是否要将改信息输出到Zipkin等服务中来收集和展示

在一个服务请求链路的调用过程中,会包吃并传递同一个Trace ID,从而将整个分布于不容微服务进程中的请求跟踪信息串联起来。以上面输出内容为例,customer-server和hello-server同属于一个前端服务请求来源,所以他们的Trace ID是相同的,处于同一个请求链路中。通过Trace ID,我们就能将所有请求过程的日志关联起来。

在Spring Boot应用中,通过引入spring-cloud-starter-sleuth依赖之后,他会自动为当前应用构建起通道跟踪机制,比如:

  • 通过RabbitMQ,Kafka等中间件传递的请求
  • 通过Zuul代理传递的请求
  • 通过RestTemplate发起的请求。

抽样收集

通过TraceID和SpanID已经实现了对分布式系统中的请求跟踪,而记录的跟踪信息最终会被分析系统收集起来,并用来实现对分布式系统的监控和分析功能。

理论上讲,收集的跟踪信息越多就可以越好的反应系统的真实运行情况,并给出更精准的预警和分析,但是在高并发的分布式系统运行时,大两的请求调用会产生海量的跟踪日志信息,如果收集过多对整个系统的性能也会造成一定的影响,同时保存大两的日志信息也需要很大的存储开销。所以在Sleuth中菜用了抽样收集的方式来为跟踪信息打商收集标记。也就是我们之前在日志信息中看到的第4个布尔类型的值,它代表了改信息是否要改后续的跟踪信息收集器获取或存储。

默认情况下,Sleuth会使用 zipkin brave的ProbabilityBasedSampler的抽样策略(现在已经不推荐使用),即以请求百分比的方式配置和收集跟踪信息,我们可以在配置文件中配置参数对其百分比值进行设置(它的默认值为 0.1,代表收集 10% 的请求跟踪信息)。

spring.sleuth.sampler.probability=0.5

而如果在配置文件中配置了 spring.sleuth.sampler.rate 的属性值,那么便会使用zipkin Brave自带的RateLimitingSampler的抽样策略。不同于ProbabilityBasedSampler菜用概况收集的策略,RateLimitingSampler是菜用的限速收集,也就是说它可以用来限制每秒跟踪请求的最大数量。

  • 如果同时设置了 spring.sleuth.sampler.ratespring.sleuth.sampler.probability 属性值,也仍然使用 RateLimitingSampler 抽样策略(即 spring.sleuth.sampler.probability 属性值无效)
  • RateLimitingSampler 策略每秒间隔接受的 trace 量设置范围:最小数字为 0,最大值为 2,147,483,647(最大 int

整合Zipkin

Zipkin是twitter的一个开源项目,它基于Google Dapper实现,我们可以用它来实现收集各个服务器上的请求链路的跟踪。并通过它提供的REST API接口来辅助查询跟踪数据以实现对分布式系统的监控程序,从而及时发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。同时,Zipkin还提供了方便的UI组件来帮助我们直观地所搜跟踪信息和分析请求地链路明细,比如可以查询某段时间内各用户请求地处理时间等。

Spring Boot 2.x 以后官网不推荐使用源码方式编译,推荐使用官网编译好的jar执行。所以我们不熟Zipkin也使用jar包的方式。

1.下载Zipkin

我这里是到maven仓库中下载的。

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

下载完成后,使用java -jar命令启动zipkin。

2.引入依赖配置

为customer-server和hello-server的项目引入zipkin的包:

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

配置文件添加zipkin的地址:

spring.zipkin.base-url=http://localhost:9411

3.测试与分析

完成所有接入Zipkin的工作后,依次讲服务起来,浏览器发送请求做测试。

点击查找按钮,下方出现服务调用的信息。注意,只有在sleuth的最后一个参数为true的时候,才会讲改跟踪信息输出给Zipkin Server。

单击其中的某一个,还可以得到Sleuth跟踪到的详细信息。其中就包括时间请求时间消耗等。

单击导航栏中的依赖按钮,还可以查看到Zipkin根据跟踪信息分析生成的系统关系请求链路依赖关系图。

持久化到mysql

在SpringBoot2.0之前的版本,Zipkin-Server端由我们自己创建项目来搭建。可以比较灵活的选择数据持久化的配置,SpringBoot2.0之后的版本,Zipkin-Server端由官方提供,无需我们自己搭建,那么如何选择去配置将数据持久化到MySQL呢?

1.创建zipkin数据库

在下载好的zipkin-serve的jar包中,找到zipkin-server-shared.yml的文件,

在里面可以找到关于mysql的持久化配置,可以看到数据库名称默认为zipkin,

初始化mysql的脚本:https://github.com/openzipkin/zipkin/blob/master/zipkin-storage/mysql-v1/src/main/resources/mysql.sql

创建的数据库如下:

2.启动zipkin

在启动zipkin的时候,以命令行的方式启动,输入mysql的参数

java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=127.0.0.1 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=root

3.测试与分析

浏览器访问,因为我这次调用服务超时了,触发了hystrix的断路器功能,所以这次有8个span。

关闭zipkin-server,然后重启,发现依然能够查询到上一次请求的服务链路跟踪数据。查看数据库表,发现数据都存储到表里了。

参考文章:

翟永超老师的《Spring Cloud微服务实战》

https://www.hangge.com/blog/cache/detail_2803.html

https://blog.csdn.net/Thinkingcao/article/details/104957540

Spring Cloud 专题之七:Sleuth 服务跟踪的更多相关文章

  1. Spring Cloud第九篇 | 分布式服务跟踪Sleuth

    ​ ​本文是Spring Cloud专栏的第九篇文章,了解前八篇文章内容有助于更好的理解本文: Spring Cloud第一篇 | Spring Cloud前言及其常用组件介绍概览 Spring Cl ...

  2. Spring Cloud Sleuth 服务跟踪 将跟踪信息存储到数据库

    参见上一篇博客:Spring Cloud Sleuth 服务跟踪 参考:zipkin使用mysql保存数据 主要在跟踪服务上配置: 在数据库创建数据库表:(可不创建,在classpath中添加对应的s ...

  3. spring cloud 专题二(spring cloud 入门搭建 之 微服务搭建和注册)

    一.前言 本文为spring cloud 微服务框架专题的第二篇,主要讲解如何快速搭建微服务以及如何注册. 本文理论不多,主要是傻瓜式的环境搭建,适合新手快速入门. 为了更好的懂得原理,大家可以下载& ...

  4. 《Spring Cloud与Docker微服务架构实战》配套代码

    不才写了本使用Spring Cloud玩转微服务架构的书,书名是<Spring Cloud与Docker微服务架构实战> - 周立,已于2017-01-12交稿.不少朋友想先看看源码,现将 ...

  5. Spring Cloud与Docker微服务架构实战 PDF版 内含目录

    Spring Cloud与Docker微服务架构实战  目录 1 微服务架构概述 1 1.1 单体应用架构存在的问题1 1.2 如何解决单体应用架构存在的问题3 1.3 什么是微服务3 1.4 微服务 ...

  6. Spring Cloud Alibaba(13)---Sleuth概述

    Sleuth概述 前言 在微服务架构中,众多的微服务之间互相调用,如何清晰地记录服务的调用链路是一个需要解决的问题.同时,由于各种原因,跨进程的服务调用失败时,运维人员希望能够通过 查看日志和查看服务 ...

  7. Spring Cloud Alibaba(15)---Sleuth+Zipkin

    SpringCloudAlibaba整合Sleuth+Zipkin 有关Sleuth之前有写过两篇文章 Spring Cloud Alibaba(13)---Sleuth概述 Spring Cloud ...

  8. spring cloud 专题一 (spring cloud 入门搭建 之 Eureka注册中心搭建)

    一.前言 本文为spring cloud 微服务框架专题的第一篇,主要讲解如何快速搭建spring cloud微服务及Eureka 注册中心 以及常用开发方式等. 本文理论不多,主要是傻瓜式的环境搭建 ...

  9. Spring Cloud 系列之 Sleuth 链路追踪(二)

    本篇文章为系列文章,未读第一集的同学请猛戳这里:Spring Cloud 系列之 Sleuth 链路追踪(一) 本篇文章讲解 Sleuth 基于 Zipkin 存储链路追踪数据至 MySQL,Elas ...

随机推荐

  1. 2、oracle用户和权限

    权限主要可以分成三类:系统权限.角色.对象权限,角色是一类系统权限的分组, Oracle 的角色存放在表 dba_roles 中,某角色包含的系统权限存放在 dba_sys_privs 中, 包含的对 ...

  2. 常用API文字版

    常用API Object类 jvm启动,默认导入的是java.lang包中的内容,该包下的内容不需要import进行导入. 概念 该类是java体系中的根类,所有对象都将该类作为直接或者间接父类 所有 ...

  3. PHP单例模式 (转)

      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ...

  4. Elasticsearch-04-master选举

    3.2 master选举机制 3.2.1 选举算法 1)bully算法 核心思想 假定所有的节点都具有一个可以比较的ID,通过比较这个ID来选举master 流程说明 节点向所有比自己ID大的节点发送 ...

  5. HanLP使用教程——NLP初体验

    话接上篇NLP的学习坑 自然语言处理(NLP)--简介 ,使用HanLP进行分词标注处词性. HanLP使用简介 HanLP是一系列模型与算法组成的NLP工具包,目标是普及自然语言处理在生产环境中的应 ...

  6. kong配置upstream实现简单的负载均衡

    目录 通过konga实现 1. 配置upstream 2. 配置Service发布 3. 配置Route,匹配规则 4. 验证结果 通过 Kong Admin API实现 1. 配置upstream ...

  7. Apache Superset 1.2.0教程 (三)—— 图表功能详解

    通过之前章节的学习,我们已经成功地安装了superset,并且连接mysql数据库,可视化了王者英雄的数据.使用的是最简单Table类型的图表,但是superset还支持非常多的图表类型. 本文我们将 ...

  8. C语言变量 类型判断

    变量三要素: 一个变量有三个基本的要素,变量的名称,变量的类型,变量的值.所以int a = 10; 变量名为a,变量的存储类型为int型,变量的值为10. 变量还有一些属性如作用范围和存储类型. 变 ...

  9. File类与常用IO流第九章——转换流

    第九章.转换流 字节编码和字符集 编码:按照某种规则将字符以二进制存储到计算机中. 解码:将存储在计算机中的二进制数按照某种规则解析显示出来. 字符编码:Character Encoding ,就是一 ...

  10. Echarts快速入门---------v客学院技术分享

    ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Safari等) ...