Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记

链路追踪Sleuth+Zipkin.跟学笔记

  • 学习目标
  • 一、什么是链路追踪
  • 二、什么是Sleuth
  • 三、专业术语
    • 1. Span
    • 2. Trace
    • 3. Annotation
  • 四、实现原理
  • 五、环境准备
  • 六、入门案例
    • 6.1.添加依赖
    • 6.2 记录日志
    • 6.3 访问
  • 七、使用Zipkin进行链路跟踪
    • 7.1. 什么是 Zipkin
    • 7.2 工作原理
    • 7.3 服务端部署
    • 7.4客户端部署
      • (1). 添加依赖
      • (2). 配置文件
      • (3). 访问
    • 7.5 存储追踪数据
      • 7.5.1 MySQL
        • (1).数据库脚本
        • (2). 部署 Zipkin 服务端
        • (3). 测试
      • 7.5.2 RabbitMQ
        • (1).启动 RabbitMQ 服务器
        • (2).部署 Zipkin 服务端
        • (3).查看队列
        • (4).客户端添加依赖
        • (5).客户端配置文件
        • (6).测试
      • 7.5.3 ElasticSearch
        • (1).启动 Elasticsearch 集群
        • (2).部署 Zipkin 服务端
        • (3).查看索引库
        • (4).客户端添加依赖
        • (5).客户端配置文件
        • (6).测试
  • 八、使用ELK分析追踪数据
    • 8.1 环境准备
    • 8.2 添加依赖
    • 8.3 日志配置
    • 8.4 查看索引库
    • 8.5测试

学习目标

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第1张图片
随着微服务架构的流行,服务按照不同的维度进行拆分,一次请求往往需要涉及到多个服务。互联网应用构建在不同的软件模块集上,这些软件模块,有可能是由不同的团队开发、可能使用不同的编程语言来实现、可能布在了几千台服务器,横跨多个不同的数据中心。因此,就需要可以帮助理解系统行为于分析性能问题的工具以便发生故障的时候,能够快速定位和解决问题。在复杂的微服务架构系统中,几乎每个前端请求都会形成一个复杂的分布式服务调用链路。
一个请求完整调用链可能如下图所示:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第2张图片

本视频跟学 优极限_2021年链路追踪教学-SpringCloud全家桶之Sleuth+Zipkin教程-核心知识点精讲
希望各位多多支持原视频,本篇文章是学习完视频之后,笔记的提炼。

一、什么是链路追踪

“链路追踪”一词是在2010年提出的,当时谷歌发布了一篇Dapper论文: Dapper, 大规模分布式系统的跟踪系统,介绍了谷歌自研的分布式链路追踪的实现原理,还介绍了他们是怎么低成本实现对应用透明的。
论文(中文翻译)
单纯的理解链路追踪,就是指一次任务的开始到结束, 期间调用的所有系统及耗时(时间跨度)都可以完整记录下来。
实Dapper一开始只是一个独立的调用链路追踪系统, 后来逐渐演化成了监控平台,并且基于监控平台孕育出了很多工具,比如实时预警、过载保护、 指标数据查询等。
除了谷歌的Dapper,还有一些其他比较有名的产品, 比如阿里的鹰眼、大众点评的CAT、Twitter 的Zipkin、Naver (著名社交软件LINE的母公司)的PinPoint以及国产开源的SkyWalking (已贡献给Apache)等。

二、什么是Sleuth

Spring Cloud Sleuth为Spring Cloud实现了分布式跟踪解决方案。兼容Zipkin, HTrace 和其他基于日志的追踪系统,例如ELK (Elasticsearch. Logstash、 Kibana) 。
Spring Cloud Sleuth提供了以下功能:

  • 链路追踪:通过Sleuth可以很清楚的看出一个请求都经过了那些服务,可以很方便的理清服务间的调用关系等。
  • 性能分析:通过Sleuth可以很方便的看出每个采样请求的耗时,分析哪些服务调用比较耗时,当服务调用的耗时随着请求量的增大而增大时,可以对服务的扩 容提供定的提醒。
  • 数据分析,优化链路:对于频繁调用一个服务,或并行调用等,可以针对业务做一些优化措施。
  • 可视化错误:对于程序未捕获的异常,可以配合Zipkin查看。

三、专业术语

1. Span

基本工作单位,一次单独的调用链可以称为一个Span, Dapper 记录的是Span的名称,以及每个Span的ID和父ID,重建在一次追踪过程中不同Span之间的关系,图中一个矩形框就是一个 Span,前端从发出请求到收到回复就是一个Span。

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第3张图片

开始跟踪的初始跨度称为root span 。该跨度的ID的值等于跟踪ID。

上图比较抽象,我们画一个容易理解的图,如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第4张图片

Dapper录了span名称,以及每个span的ID和父spanID,以重建在一次追踪过程中不同span之间的关系。如果一个span没有父ID被称为root span。所有span都挂在一个特定的Trace上,也共用一个trace id。
图示为Help.Call微服务模块展开的具体结构。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第5张图片

2. Trace

一列Span组成的树状结构,一个Trace认为是一次完整的链路, 内部包含n多个Span。Trace 和Span存在一对多的关系,Span与Span之间存在父子关系。
举个例子:户端调用服务A、服务B、服务C、服务F,而每个服务例如C就是一个Span,如果在服务C中另起线程调用了D,那么D就是C的子Span,如果在服务D中另起线程调用了E,那么E就是D的子Span,这个C->D->E的链路就是条Trace。如果链路追踪系统做好了,链路数据有了,借助前端解析和渲染工具,可以达到下图中的效果:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第6张图片
我们后面要学习的zipkin的可视化界面如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第7张图片

3. Annotation

用来及时记录一个事件的存在,一些核心annotations用来定义一个请求的开始和结束。

  • cs-Client Sent: 客户端发起一个请求,这个annotation描述了这个span的开始;
  • sr-Server Received:服务端获得请求并准备开始处理它,如果sr减去cs时间戳便可得到网络延迟;
  • ss-Server Sent:求处理完成(当请求返回客户端),如果 ss减去sr时间戳便可得到服务端处理请求需要的时间;
  • cr- Client Received: 表示span结束户端成功接收到服务端的回复,如果cr减去cs时间戳便可得到客户端从服务端获取回复的所有所需时间。

公式:
网络延迟 = sr - cs
服务端处理请求需要的时间 = ss - sr
客户端从服务端获取回复的所有所需时间 = cr - cs

四、实现原理

如果想知道一个接口在哪个环节出现了问题,就必须清楚该接口调用了哪些服务,以及调用的顺序,如果把这些服务串起来,看起来就像链条一样,我们称其为调用链

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第8张图片
想要实现调用链,就要为每次调用做个标识,然后将服务按标识大小排列,可以更清晰地看出调用顺序,我们暂且将该标识命名为spanid

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第9张图片
实际场中,我们需要知道某次请求调用的情况,所以只有spanid还不够,得为每次请求做个唯一标识, 这样才能根据标识查出本次请求调用的所有服务,而这个标识我们命名为traceid

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第10张图片
现在根据spanid可以轻易地知道被调用服务的先后顺序,但无法体现调用的层级关系,正如下图所示,多个服务可能是逐级调用的链条,也可能是同时被同一个服务调用。

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第11张图片
所以应该每次都记录下是谁调用的,我们用parentid 作为这个标识的名字。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第12张图片

到现在,已经知道调用顺序和层级关系了,但是接口出现问题后,还是不能找到出问题的环节,如果某个服务有问题,那个被调用执行的服务一定耗时很长, 要想计算出耗时,上述的三个标识还不够, 还需要加上时间戳,时间戳可以更精细一点,精确到微秒级。
增加请求发起的timestamp
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第13张图片
只记录发起调用时的时间戳还算不出耗时,要记录下服务返回时的时间戳,有始有终才能算出时间差,既然返回的也记了,就把上述的三个标识都记一下吧, 不然区分不出是谁的时间戳。

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第14张图片

虽然能计算出从服务调用到服务返回的总耗时,但是这个时间包含了服务的执行时间和网络延迟,有时候我们需要区分出这两
类时间以方便做针对性优化。那如何计算网络延迟呢?我们可以把调用和返回的过程分为以下四个事件。

  • Client Sent简称cs,客户端发起调用请求到服务端。
  • Server Received简称sr.指服务端接收到了客户端的调用请求。
  • Server Sent简称ss,指服务端完成了处理,准备将信息返给客户端。
  • Client Received简称cr,指客F端接收到了服务端的返回信息。

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第15张图片

假如在这四个事件发生时记录下时间戳,就可以轻松计算出耗时,比如:

sr减去cs就是调用时的网络延迟
ss 减去sr就是服务执行时间
cr减去ss就是服务响应的延迟
cr减cs就是整个服务调用执行的时间

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第16张图片
其实span内除了记这几个参数之外,还可以记录一其他信息,比如发起调用服务名称、被调服务名称、返回结果、IP、调用服务的名称等,最后,我们再把相同parentid的span信息合成一个大的span块,就完成了一个完整的调用链。

以上原型图来自张以诺的绘制。

五、环境准备

  • eureka-server :注册中心
  • eureka-server02 :注册中心
  • gateway-server : Spring Cloud Gateway服务网关
  • product-service :商品服务,提供了根据主键查询商品接口http://localhost:7870/product/{id} 根据多个主键查询商品接口http://localhost :7870/product/listByIds
  • order-service :订单服务,提供了根据主键查询订单接口http://localhost :9090/order/{id}且订单服务调用商品服务。

课件资料:
百度云-课件
提取码:c8cp
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第17张图片
在IDEA中打开
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第18张图片
导入项目后如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第19张图片
然后顺序启动:
eureka-server
eureka-server2
gateway
order-service
product-service

启动eureka-server和eureka-server2的时候增加配置

register-with-eureka: false #是否将自己注册到eureka中
    fetch-registry: false #是否从eureka中拉去信息列表

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第20张图片
这里注意,如果出现子项目@SpringBootApplication报红问题
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第21张图片
解决方案:右键-maven-reload project
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第22张图片
验证Eureka是否启动成功
访问

http://localhost:8761/

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第23张图片

验证product-service服务是否启动成功
访问

http://localhost:7070/product/listByIds?id=1&id=2

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第24张图片
验证order-service服务是否启动成功
访问

http://localhost:9090/order/1

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第25张图片
验证网关gateway是否启动成功
访问

http://localhost:9000/order-service/order/1

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第26张图片
访问

http://localhost:9000/product-service/product/listByIds?id=1&id=2

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第27张图片
发现都没有问题

六、入门案例

在需要进行链路追踪的项目中(服务网关、商品服务、订单服务)添加 spring-cloud-starter-sleuth 依赖。

6.1.添加依赖


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-sleuthartifactId>
dependency>

6.2 记录日志

在需要链路追踪的项目中(服务网关、商品服务、订单服务)添加 logback.xml 日志文件,内容如下(logback 日志的输出级别需要是 DEBUG 级别):
注意修改

< property name=“log.path”
value=“${catalina.base}/gateway-server/logs”/ >

中项目名称。

日志核心配置:

%d{yyyy-MM-dd HH:mm:ss.SSS}
[${applicationName},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}] [%thread]%-5level %logger{50} - %msg%n

注意:资料中提供的日志文件有编码问题,直接拷贝我这里的即可
logback.xml






<configuration scan="true" scanPeriod="10 seconds">
    
    <contextName>my_logbackcontextName>
    
    <property name="log.path" value="${catalina.base}/gateway-server/logs"/>
    
    <springProperty scope="context" name="applicationName"
                    source="spring.application.name" defaultValue="localhost"/>
    
    <property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS}
[${applicationName},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-}] [%thread] %-5level
%logger{50} - %msg%n"/>
    
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUGlevel>
        filter>
        <encoder>
            <pattern>${LOG_PATTERN}pattern>
            
            <charset>UTF-8charset>
        encoder>
    appender>
    
    
    <appender name="DEBUG_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${log.path}/log_debug.logfile>
        
        <encoder>
            <pattern>${LOG_PATTERN}pattern>
            <charset>UTF-8charset> 
        encoder>
        
        <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            
            <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.logfileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            <maxHistory>15maxHistory>
        rollingPolicy>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUGlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>
    
    <appender name="INFO_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${log.path}/log_info.logfile>
        
        <encoder>
            <pattern>${LOG_PATTERN}pattern>
            <charset>UTF-8charset>
        encoder>
        
        <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.logfileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            <maxHistory>15maxHistory>
        rollingPolicy>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>INFOlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>
    
    <appender name="WARN_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${log.path}/log_warn.logfile>
        
        <encoder>
            <pattern>${LOG_PATTERN}pattern>
            <charset>UTF-8charset> 
        encoder>
        
        <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.logfileNamePattern>
            
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            <maxHistory>15maxHistory>
        rollingPolicy>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>WARNlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>
    
    <appender name="ERROR_FILE"
              class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <file>${log.path}/log_error.logfile>
        
        <encoder>
            <pattern>${LOG_PATTERN}pattern>
            <charset>UTF-8charset> 
        encoder>
        
        <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.logfileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MBmaxFileSize>
            timeBasedFileNamingAndTriggeringPolicy>
            
            <maxHistory>15maxHistory>
            
            <totalSizeCap>10GBtotalSizeCap>
        rollingPolicy>
        
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERRORlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        filter>
    appender>
    
    
    
    
    
    
    
    <logger name="myLog" level="INFO" additivity="false">
        <appender-ref ref="CONSOLE"/>
    logger>
    
    <root level="DEBUG">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="DEBUG_FILE"/>
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="WARN_FILE"/>
        <appender-ref ref="ERROR_FILE"/>
    root>
configuration>

这里注意项目名称和日志名称一致
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第28张图片
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第29张图片

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第30张图片

6.3 访问

访问之前,添加日志的项目要重启
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第31张图片
重启之后发现生成了文件
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第32张图片

访问:

http://localhost:9000/order-service/order/1

结果如下:
服务网关打印信息:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第33张图片

[gateway-server,f82de2d68493f0cb,f82de2d68493f0cb]

商品服务打印信息
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第34张图片

[product-service,f82de2d68493f0cb,93fc5e739328a597]

订单服务打印信息

[order-service,f82de2d68493f0cb,a94f977efaf08f05]

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第35张图片
通过打印信息可以得知,
整个链路的 traceId为:f82de2d68493f0cb,
spanId 为:93fc5e739328a597 和 a94f977efaf08f05 。

查看日志文件并不是一个很好的方法,当微服务越来越多日志文件也会越来越多,查询工作会变得越来越麻烦,Spring 官方推荐使用Zipkin 进行链路跟踪。Zipkin 可以将日志聚合,并进行可视化展示和全文检索。

七、使用Zipkin进行链路跟踪

7.1. 什么是 Zipkin

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第36张图片
ZIPKIN官网
ZIPKIN是 Twitter 公司开发贡献的一款开源的分布式实时数据追踪系统(Distributed TrackingSystem),基于 Google Dapper 的论文设计而来,其主要功能是聚集各个异构系统的实时监控数据。

它可以收集各个服务器上请求链路的跟踪数据,并通过 Rest API 接口来辅助我们查询跟踪数据,实现对分布式系统的实时监控,及时发现系统中出现的延迟升高问题并找出系统性能瓶颈的根源。除了面向开发的 API 接口之外,它还提供了方便的 UI 组件,每个服务向 Zipkin 报告计时数据,Zipkin 会根据调用关系生成依赖关系图,帮助我们直观的搜索跟踪信息和分析请求链路明细。Zipkin 提供了可插拔数据存储方式:In-Memory、MySql、Cassandra 以及 Elasticsearch。

分布式跟踪系统还有其他比较成熟的实现,例如:Naver 的 PinPoint、Apache 的 HTrace、阿里的鹰眼 Tracing、京东的 Hydra、新浪的 Watchman,美团点评的 CAT,Apache 的 SkyWalking 等。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第37张图片

7.2 工作原理

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第38张图片
共有四个组件构成了 Zipkin:

  • Collector :收集器组件,处理从外部系统发送过来的跟踪信息,将这些信息转换为 Zipkin 内部处理的 Span 格式,以支持后续的存储、分析、展示等功能。
  • Storage :存储组件,处理收集器接收到的跟踪信息,默认将信息存储在内存中,可以修改存储策略使用其他存储组件,支持 MySQL,Elasticsearch 等。
  • Web UI :UI 组件,基于 API 组件实现的上层应用,提供 Web 页面,用来展示 Zipkin 中的调用链和系统依赖关系等。
  • RESTful API :API 组件,为 Web 界面提供查询存储中数据的接口。

Zipkin 分为两端,一个是 Zipkin 服务端,一个是 Zipkin 客户端,客户端也就是微服务的应用,客户端会配置服务端的 URL 地址,一旦发生服务间的调用的时候,会被配置在微服务里面的 Sleuth 的监听器监听,并生成相应的 Trace 和 Span 信息发送给服务端。发送的方式有两种,一种是消息总线的方式如 RabbitMQ 发送,还有一种是 HTTP 报文的方式发送。

7.3 服务端部署

服务端是一个独立的可执行的 jar 包,官方下载地址:ZIPKIN下载地址,使用 java -jar zipkin.jar 命令启动,端口默认为9411 。我们下载的 jar 包为:zipkin-server-2.20.1-exec.jar。
资料中带这个jar包:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第39张图片

启动命令如下:

java -jar zipkin-server-2.20.1-exec.jar

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第40张图片
启动后如下:
在这里插入图片描述

访问:

http://localhost:9411/ 

结果如下:
目前最新版界面。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第41张图片
之前旧版本界面。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第42张图片

7.4客户端部署

(1). 添加依赖

在需要进行链路追踪的项目中(服务网关、商品服务、订单服务)添加 spring-cloud-starter-zipkin 依赖。


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-zipkinartifactId>
dependency>

(2). 配置文件

在需要进行链路追踪的项目中(服务网关、商品服务、订单服务)配置 Zipkin 服务端地址及数据传输方式。默认即如下配置。

spring:
  zipkin:
    base-url: http://localhost:9411/ # 服务端地址
    sender:
      type: web # 数据传输方式,web 表示以 HTTP 报文的形式向服务端
  sleuth:
    sampler:
      probability: 1.0 # # 收集数据百分比,默认 0.1(10%)

这里type:web 是按照Http报文的方式发送的,后续会更改为其它方式。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第43张图片
更改玩之后重启项目
现在的调用链路如下:
client -> gateway -> order-service -> product-service

(3). 访问

访问:

http://localhost:9000/order-service/order/1 

结果如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第44张图片

新版操作如下:访问:

http://localhost:9411/ 

根据时间过滤点击 搜索 结果如下:
在这里插入图片描述
点击后结果如下:

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第45张图片
我们多访问几次订单或者库存,这里zipkin也会产生几条数据
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第46张图片
点击对应的追踪信息可查看请求链路详细。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第47张图片
查看时间戳
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第48张图片
还可以下载为JSON的数据
在这里插入图片描述

支持条件查询
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第49张图片

通过依赖可以查看链路中服务的依赖关系。而且还有服务调度的动态展示,有个小球移动,非常人性化。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第50张图片

旧版操作如下:
访问:

http://localhost:9411/ 

点击查找结果如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第51张图片
点击对应的追踪信息可查看请求链路详细。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第52张图片
通过依赖可以查看链路中服务的依赖关系。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第53张图片

而目前我们的所有配置,只要重启都没有了,那我们就需要存储追踪服务。

7.5 存储追踪数据

Zipkin Server 默认存储追踪数据至内存中,这种方式并不适合生产环境,一旦 Server 关闭重启或者服务崩溃,就会导致历史数据消失。Zipkin 支持修改存储策略使用其他存储组件,支持 MySQL,Elasticsearch 等。

7.5.1 MySQL

(1).数据库脚本

打开 MySQL 数据库,创建 zipkin 库,执行以下 SQL 脚本。
官网地址:官网地址

脚本在资料中有,直接去mysql中运行即可
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第54张图片
创建数据库

CREATE DATABASE zipkin;
USE zipkin;

之后执行脚本,出现3个表
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第55张图片

(2). 部署 Zipkin 服务端

这里就不能通过jar的默认形式直接启动服务端了,而是要添加启动参数,重新部署服务端:
官网地址:Zipkin服务端用于MySql

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

在这里插入图片描述

(3). 测试

访问:

http://localhost:9000/order-service/order/1 

查看数据库结果如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第56张图片

在 MySQL 模式下,每次启动服务端时,服务端会从数据库加载链路信息展示至 Web 界面。
我们用CTRL + C,esc 退出Zipkin,然后此时访问zipkin服务端,发现无法访问,那之前的数据丢失了吗,我们重启zipkin服务端看看
在这里插入图片描述
访问

http://localhost:9411/zipkin/

发现因为保存到了mysql中之前的访问信息并没有丢失
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第57张图片

7.5.2 RabbitMQ

之前的课程中我们已经学习过 RabbitMQ 的详细使用,这里不再过多赘述,直接开启使用即可。

目前的链路模式是:
client

(1).启动 RabbitMQ 服务器

开启虚拟机,通过以下命令启动 RabbitMQ 服务端。

systemctl start docker
docker start mq

访问

ip:15672

进入mq的图形界面,发现此时没有队列
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第58张图片

(2).部署 Zipkin 服务端

添加启动参数,重新部署服务端:
官网地址:官网部署-mq

java -jar zipkin-server-2.20.1-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=localhost --MYSQL_TCP_PORT=3306 --MYSQL_USER=root --MYSQL_PASS=root --MYSQL_DB=zipkin --RABBIT_ADDRESSES=192.168.10.101:5672 --RABBIT_USER=guest --RABBIT_PASSWORD=guest --RABBIT_VIRTUAL_HOST=/ --RABBIT_QUEUE=zipkin

启动参数中包含 MySQL 和 RabbitMQ 的配置,实现基于 MQ 并存储链路信息至 MySQL,如下图:

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第59张图片

(3).查看队列

访问:http://192.168.10.101:15672/#/queues 可以看到已经创建好了 zipkin 队列。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第60张图片
这里为了看见消息消费的过程,我们停止服务端,并且清空mysql中zipkin数据库的表。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第61张图片
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第62张图片

(4).客户端添加依赖

官网文档:官方文档
在网关、订单服务、产品服务都添加


        <dependency>
            <groupId>org.springframework.amqpgroupId>
            <artifactId>spring-rabbitartifactId>
        dependency>

(5).客户端配置文件

application.yml

spring:
  application:
    name: gateway-server # 应用名称
  cloud:
    gateway:
      discovery:
        locator:
          # 是否与服务发现组件进行结合,通过 serviceId 转发到具体服务实例。
          enabled: true                  # 是否开启基于服务发现的路由规则
          lower-case-service-id: true    # 是否将服务名称转小写
  zipkin:
    base-url: http://localhost:9411/ # 服务端地址
    sender:
      # ype: web # 数据传输方式,web 表示以 HTTP 报文的形式向服务端
      type: rabbit # 数据传输方式,web 表示以 HTTP 报文的形式向服务端
  sleuth:
    sampler:
      probability: 1.0 # # 收集数据百分比,默认 0.1(10%)
  rabbitmq:
    host: 192.168.10.101
    port: 5672
    username: guest
    password: guest
    virtual-host: /
    listener:
      direct:
        retry:
          enabled: true
          max-attempts: 5
          initial-interval: 5000
      simple:
        retry:
          enabled: true
          max-attempts: 5
          initial-interval: 5000

Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第63张图片
配置完后重启服务

(6).测试

先关闭 Zipkin 服务端,访问:

http://localhost:9000/order-service/order/1 

客户端已将链路追踪数据写入队列当中:

启动 Zipkin 服务端后,队列中消息被堆积
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第64张图片
此时我们再此启动Zipkin的服务端

java -jar zipkin-server-2.20.1-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=localhost --MYSQL_TCP_PORT=3306 --MYSQL_USER=root --MYSQL_PASS=root --MYSQL_DB=zipkin --RABBIT_ADDRESSES=192.168.10.101:5672 --RABBIT_USER=guest --RABBIT_PASSWORD=guest --RABBIT_VIRTUAL_HOST=/ --RABBIT_QUEUE=zipkin

启动后队列中消息被消费
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第65张图片

链路追踪数据被存储至 MySQL。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第66张图片

7.5.3 ElasticSearch

之前的课程中我们已经学习过 Elasticsearch 的详细使用,这里不再过多赘述,直接开启使用即可。

(1).启动 Elasticsearch 集群

启动集群,访问:

http://192.168.10.101:9200/ 

结果如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第67张图片

启动 head 插件,访问:http://192.168.10.101:9100/ 结果如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第68张图片

(2).部署 Zipkin 服务端

添加启动参数,重新部署服务端:
官网地址:Zipkin服务端

java -jar zipkin-server-2.20.1-exec.jar --STORAGE_TYPE=elasticsearch --ES_HOSTS=http://192.168.10.101:9200/,http://192.168.10.102:9200/,http://192.168.10.103:9200/ --RABBIT_ADDRESSES=192.168.10.101:5672 --RABBIT_USER=guest --RABBIT_PASSWORD=guest --RABBIT_QUEUE=zipkin

启动参数中包含 Elasticsearch 和 RabbitMQ 的配置,实现基于 MQ 并存储链路信息至Elasticsearch。

(3).查看索引库

访问:http://192.168.10.101:9100 可以看到已经创建好了 zipkin 索引库。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第69张图片

(4).客户端添加依赖

官网文档:官方文档


<dependency>
    <groupId>org.springframework.amqpgroupId>
    <artifactId>spring-rabbitartifactId>
dependency>

(5).客户端配置文件

spring:
 zipkin:
   base-url: http://localhost:9411/ # 服务端地址
   sender:
     type: rabbit
   rabbitmq:
     queue: zipkin                  # 队列名称
 rabbitmq:
   host: 192.168.10.101             # 服务器 IP
   port: 5672                       # 服务器端口
   username: guest                  # 用户名
   password: guest                  # 密码
   virtual-host: /                  # 虚拟主机地址
   listener:
     direct:
       retry:
         enabled: true              # 是否开启发布重试
         max-attempts: 5            # 最大重试次数
         initial-interval: 5000     # 重试间隔时间(单位毫秒)
     simple:
       retry:
         enabled: true              # 是否开启消费者重试
         max-attempts: 5            # 最大重试次数
         initial-interval: 5000     # 重试间隔时间(单位毫秒)
 sleuth:
   sampler:
     probability: 1.0               # 收集数据百分比,默认 0.1(10%)

(6).测试

访问:

http://localhost:9000/order-service/order/1 

查看索引库结果如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第70张图片

八、使用ELK分析追踪数据

ELK 是 elastic 公司提供的一套完整的日志收集以及展示的解决方案,是三个产品的首字母缩写,分别是 ElasticSearch、Logstash 和 Kibana。

  • Elasticsearch 简称 ES:实时的分布式搜索和分析引擎,它可以用于全文搜索,结构化搜索以及分析。建立在全文搜索引擎 Apache Lucene 基础上的搜索引擎,使用 Java 语言编写。
  • Logstash:具有实时传输能力的数据收集引擎,将各种各样的数据进行收集、解析,并发送给ES。使用 Ruby 语言编写。
  • Kibana:为 Elasticsearch 提供了分析和可视化的 Web 平台。它可以在 Elasticsearch 的索引中查找,交互数据,并生成各种维度表格、图形。
  • Beats:一组轻量级采集程序的统称,使用 Go 语言编写。以下是 elastic 官方支持的 5 种 beats,事实上,伟大的开源力量早已创造出大大小小几十甚至上百种 beats,只有你没想到的,没有beats 做不到的:
    • Filebeat:进行文件和目录采集,主要用于收集日志数据。
    • Winlogbeat:专门针对 Windows 的 event log 进行的数据采集。
    • Metricbeat:进行指标采集,指标可以是系统的,也可以是众多中间件产品的,主要用于监控系统和软件的性能。
    • Packetbeat:通过网络抓包、协议分析,对一些请求响应式的系统通信进行监控和数据收集,可以收集到很多常规方式无法收集到的信息。
    • Heartbeat:系统间连通性检测,比如 icmp,tcp,http 等系统的连通性监控。

8.1 环境准备

之前的课程中我们已经学习过 ELK 的详细使用,这里不再过多赘述,直接开启使用即可。文中使用的 ELK 版本统一为 7.5.2。

  • 本文使用的 Elasticsearch 集群地址为:
    192.168.10.101:9200
    192.168.10.102:9200
    192.168.10.103:9200
  • 本文使用的 Logstash 的地址为:
    192.168.10.101:9250
  • 本文使用的 Kibana 的地址为:
    192.168.10.101:5601

Logstash 运行时指定的配置文件 log-to-es.conf 内容如下:

# 数据入口
input {
 tcp {
 mode => "server"
 host => "192.168.10.101"
 port => 9250
 }
}
# 处理数据
filter {
 # 获取 @timestamp 的值并加上 8*60*60(北京时间比 logstash 中@timestamp 晚了 8 小
时),然后赋值给变量 timestamp。
 ruby { 
 code => "event.set('timestamp', event.get('@timestamp').time.localtime + 
8*60*60)"
}
 # 将 timestamp 值重新赋值给 @timestamp
 ruby {
 code => "event.set('@timestamp', event.get('timestamp'))"
 }
 # 删除变量 timestamp
 mutate {
 remove_field => ["timestamp"]
 }
}
# 数据出口
output {
 elasticsearch {
 hosts => ["192.168.10.101:9200", "192.168.10.102:9200", 
"192.168.10.103:9200"]
 index => "applog"
 }
}

8.2 添加依赖

在需要进行链路追踪的项目中(服务网关、商品服务、订单服务)添加 logstash-logback-encoder 依赖。


<dependency>
    <groupId>net.logstash.logbackgroupId>
    <artifactId>logstash-logback-encoderartifactId>
    <version>6.3version>
dependency>

8.3 日志配置

在需要进行链路追踪的项目中(服务网关、商品服务、订单服务)添加 logstash 输出 JSON 格式数据 。
logback.xml


<configuration scan="true" scanPeriod="10 seconds">
    
   ...
    
    <appender name="LOGSTASH_PATTERN"
class="net.logstash.logback.appender.LogstashTcpSocketAppender">
        
        <destination>192.168.10.101:9250destination>
        
<encoder
class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
            <providers>
                <pattern>
                    <pattern>
                       {
                       "severity": "%level",
                       "service": "${springAppName:-}",
                       "trace": "%X{X-B3-TraceId:-}",
                       "span": "%X{X-B3-SpanId:-}",
                       "exportable": "%X{X-Span-Export:-}",
                       "pid": "${PID:-}",
                       "thread": "%thread",
                       "class": "%logger{40}",
                       "rest": "%message"
                       }
                    pattern>
                pattern>
            providers>
        encoder>
    appender>
    
    <root level="DEBUG">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="LOGSTASH_PATTERN"/>
        <appender-ref ref="DEBUG_FILE"/>
        <appender-ref ref="INFO_FILE"/>
        <appender-ref ref="WARN_FILE"/>
        <appender-ref ref="ERROR_FILE"/>
    root>
    
   ...
configuration>

8.4 查看索引库

访问:http://192.168.10.101:9100 可以看到已经创建好了 applog 索引库。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第71张图片

8.5测试

访问:http://localhost:9000/order-service/order/1 查看索引库结果如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第72张图片
访问:http://192.168.10.101:5601/ Kibana 首页
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第73张图片
添加 applog 索引库。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第74张图片
不使用时间过滤器。
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第75张图片
搜索 gateway 结果如下:
Spring Cloud链路追踪Sleuth+Zipkin.跟学笔记_第76张图片

你可能感兴趣的:(Spring,Cloud微服务,spring,cloud,java,spring,zipkin,sleuth)