欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring Cloud Sleuth

程序员文章站 2022-06-12 15:24:25
...

转载请表明出处 https://blog.csdn.net/Amor_Leo/article/details/87891442 谢谢

Spring Cloud Sleuth概述

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

  1. Span(跨度) : Span是基本的工作单元。Span包括一个64位的唯一ID,一个64位trace码,描述信息,时间戳事件,key-value 注解(tags),span处理者的ID(通常为IP)。最开始的初始Span称为根span,此span中span id和 trace id值相同。
  2. Trance(跟踪) : 包含一系列的span,它们组成了一个树型结构,用一个64位的唯一ID标识。
  3. Annotation(标注) : 用于及时记录存在的事件。常用的Annotation如下:
    • cs - Client Sent:客户端发送一个请求,表示span的开始
    • sr - Server Received:服务端接收请求并开始处理它。(sr-cs)等于网络的延迟
    • ss - Server Sent:服务端处理请求完成,开始返回结束给服务端。(ss-sr)表示服务端处理请求的时间
    • cr - Client Received:客户端完成接受返回结果,此时span结束。(cr-sr)表示客户端接收服务端数据的时间
      Spring Cloud Sleuth

Spring Cloud Sleuth搭建

基本

  • pom
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
  </dependency>
  • yml
server:
  port: 8000
spring:
  application:
    name: provider-server
logging:
  level:
    org.springframework.cloud.sleuth: DEBUG

与ELK整合

  • pom
  <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
  </dependency>
  <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
  </dependency>
  <dependency>
    <groupId>net.logstash.logback</groupId>
    <artifactId>logstash-logback-encoder</artifactId>
    <version>4.6</version>
  </dependency>
  • yml
    application.yml
server:
  port: 8000
logging:
  level:
    root: INFO
    org.springframework.cloud.sleuth: DEBUG

bootstrap.yml

spring:
  application:
    name: provider-server
# 注意:本例中的spring.application.name只能放在bootstrap.*文件中,不能放在application.*文件中,因为我们使用了自定义的logback-spring.xml。
# 如果放在application.*文件中,自定义的logback文件将无法正确读取属性
  • logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <include resource="org/springframework/boot/logging/logback/defaults.xml" />
  
  <springProperty scope="context" name="springAppName" source="spring.application.name" />
  <!-- Example for logging into the build folder of your project -->
  <property name="LOG_FILE" value="${BUILD_FOLDER:-build}/${springAppName}" />
  
  <property name="CONSOLE_LOG_PATTERN"
    value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr([${springAppName:-},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-B3-ParentSpanId:-},%X{X-Span-Export:-}]){yellow} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />

  <!-- Appender to log to console -->
  <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
      <!-- Minimum logging level to be presented in the console logs -->
      <level>DEBUG</level>
    </filter>
    <encoder>
      <pattern>${CONSOLE_LOG_PATTERN}</pattern>
      <charset>utf8</charset>
    </encoder>
  </appender>

  <!-- Appender to log to file -->
  <appender name="flatfile" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_FILE}</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_FILE}.%d{yyyy-MM-dd}.gz</fileNamePattern>
      <maxHistory>7</maxHistory>
    </rollingPolicy>
    <encoder>
      <pattern>${CONSOLE_LOG_PATTERN}</pattern>
      <charset>utf8</charset>
    </encoder>
  </appender>
  
  <!-- Appender to log to file in a JSON format -->
  <appender name="logstash" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_FILE}.json</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_FILE}.json.%d{yyyy-MM-dd}.gz</fileNamePattern>
      <maxHistory>7</maxHistory>
    </rollingPolicy>
    <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
      <providers>
        <timestamp>
          <timeZone>UTC</timeZone>
        </timestamp>
        <pattern>
          <pattern>
            {
              "severity": "%level",
              "service": "${springAppName:-}",
              "trace": "%X{X-B3-TraceId:-}",
              "span": "%X{X-B3-SpanId:-}",
              "parent": "%X{X-B3-ParentSpanId:-}",
              "exportable": "%X{X-Span-Export:-}",
              "pid": "${PID:-}",
              "thread": "%thread",
              "class": "%logger{40}",
              "rest": "%message"
            }
          </pattern>
        </pattern>
      </providers>
    </encoder>
  </appender>
  
  <root level="INFO">
    <appender-ref ref="console" />
    <appender-ref ref="logstash" />
    <!--<appender-ref ref="flatfile"/> -->
  </root>
</configuration>

其中logstash.conf文件:
Spring Cloud Sleuth

与Zipkin整合

  • zipkin server
    • pom
      <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-autoconfigure-ui</artifactId>
      </dependency>
      <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-server</artifactId>
      </dependency>
    
    • yml
    server:
      port: 9411
    spring:
      application:
    	name: zipkin-server
    
    • Application类
    @EnableZipkinServer  	//默认采用HTTP通信方式启动ZipkinServer
    @SpringBootApplication
    public class ZipkinServerApplication {
    	public static void main(String[] args) {
    		SpringApplication.run(ZipkinServerApplication.class, args);
    	}
    
  • web Client
    • pom
      <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-sleuth</artifactId>
      </dependency>
      <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-sleuth-zipkin</artifactId>
      </dependency>
      
    • yml
      server:
        port: 8000
      spring:
        application:
          name: provider-server
        zipkin:
          enabled: true
          base-url: http://localhost:9411  #指定zipkin-server的服务地址,如果加了Eureka,可以在URL中传递Zipkin的服务ID
        sleuth:
          sampler:
            percentage: 1.0  #设置采样率,默认0.1,为了测试设置100%采集
      

使用消息中间件收集消息

  • zipkin server
    • pom
      <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-autoconfigure-ui</artifactId>
      </dependency>
      <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-server</artifactId>
      </dependency>
      
      <!-- 使用消息的方式收集数据(使用rabbitmq) -->
      <dependency>
        <groupId>io.zipkin.java</groupId>
        <artifactId>zipkin-autoconfigure-collector-rabbitmq</artifactId>
        <version>2.3.1</version>
      </dependency>
      
    • yml
      server:
        port: 9411
      spring: 
        application:
      	name: zipkin-server
      zipkin:
        collector:
          rabbitmq:
            addresses: 192.168.0.111:5672
            password: admin
            username: admin
            queue: zipkin
      
    • Application类
      @EnableZipkinServer   
      @SpringBootApplication
      public class ZipkinServerApplication {
      	public static void main(String[] args) {
      		SpringApplication.run(ZipkinServerApplication.class, args);
      	}
      
  • Web Client
    • pom
       <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
       </dependency>
       <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-starter-zipkin</artifactId>
       </dependency>
       <dependency>
         <groupId>org.springframework.amqp</groupId>
         <artifactId>spring-rabbit</artifactId>
       </dependency>
      
    • yml
      server:
        port: 8000
      spring:
        application:
          name: provider-server
        sleuth:
          sampler:
            percentage: 1.0
        rabbitmq:
          host: 192.168.0.111
          port: 5672
          username: admin
          password: admin
        zipkin:
          rabbitmq:
            queue: zipkin
      

数据持久化(ES)

  • zipkin server
    • pom
        <dependency>
          <groupId>io.zipkin.java</groupId>
          <artifactId>zipkin-autoconfigure-ui</artifactId>
        </dependency>
        <dependency>
          <groupId>io.zipkin.java</groupId>
          <artifactId>zipkin-server</artifactId>
        </dependency>
        <dependency>
          <groupId>io.zipkin.java</groupId>
          <artifactId>zipkin-autoconfigure-collector-rabbitmq</artifactId>
          <version>2.3.1</version>
        </dependency>
        <!-- 支持Elasticsearch 2.x - 6.x -->
        <dependency>
          <groupId>io.zipkin.java</groupId>
          <artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId>
          <version>2.3.1</version>
        </dependency>
      
    • yml
      server:
        port: 9411
      zipkin:
        collector:
          rabbitmq:
            addresses: 192.168.0.111:5672
            password: admin
            username: admin
            queue: zipkin
        storage:
          type: elasticsearch  #表示zipkin数据存储方式是elasticsearch
          elasticsearch:
            cluster: elasticsearch
            hosts: http://192.168.0.111:9200
            index: zipkin
            index-shards: 5
            index-replicas: 1
      
    • Application类
      @EnableZipkinServer   
      @SpringBootApplication
      public class ZipkinServerApplication {
      	public static void main(String[] args) {
      		SpringApplication.run(ZipkinServerApplication.class, args);
      	}