SpringCloudStarterSleuth搭建&使用

是什么

Spring Cloud Sleuth是Spring Cloud生态系统中的一个分布式跟踪解决方案,可以用于跟踪微服务应用程序中的请求链路。它通过在请求中添加唯一标识符(Trace ID)和调用标识符(Span ID),来跟踪整个请求在分布式系统中的调用过程。Sleuth还支持将跟踪信息导出到Zipkin等跟踪系统中,以便更好地分析和监控微服务应用程序的性能和运行状况。

核心的概念

Trace(跟踪)
跟踪是一次请求的完整路径,由多个Span(调用)组成。跟踪ID是整个跟踪的唯一标识符,可以跨越多个微服务应用程序。在Sleuth中,跟踪ID是通过生成一个随机的64位数字来实现的。

Span(调用)
Span是跟踪中的一个节点,表示一次服务调用或一次操作。它包括Span ID(调用标识符)、Parent ID(父调用标识符)等信息。

Trace Context
Trace Context是一个全局上下文,包括Trace ID、Span ID、Parent ID等信息。Sleuth通过在请求中添加Trace Context,来跟踪整个请求在分布式系统中的调用过程。

Exporter(导出器)
Sleuth支持将跟踪信息导出到Zipkin等跟踪系统中,以便更好地分析和监控微服务应用程序的性能和运行状况。Sleuth提供了一系列导出器,可以方便地将跟踪信息导出到不同的跟踪系统中。

服务搭建

下载ZipKin Server

根据不同环境使用不同的方式,下载地址

运行ZipKin Server

  1. 在下载的jar包目录执行cmd,见下图

    Java -jar zipkin-server-2.24.0-exec.jar
    

image-20230217165200690

  1. 浏览器访问看看是否启动

    127.0.0.1:9411

    image-20230217165310864

项目配置

用三个项目之间连续调用来测试,注册中心使用的consul

firstProject->secondProject->thirdProject

三个项目的POM

都引入下面GAV

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-consul-discovery -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
            <version>2.2.8.RELEASE</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-actuator -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>3.0.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.springframework.cloud/spring-cloud-starter-zipkin -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
            <version>2.2.8.RELEASE</version>
        </dependency>
        <!-- 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.8.RELEASE</version>
        </dependency>

    </dependencies>

三个项目的Yml

#firstProject的Yml---------------------------
server:
  port: 5001
spring:
  application:
    name: firstProject #注册到zk的消费者名称
  zipkin:
    base-url: http://10.20.30.94:9411
  sleuth:
    sampler:
      #采样率值介于 0 到 1 之间,1 则表示全部采集
      probability: 1
  cloud:
    consul:
      host: 10.20.30.94:8500
      port: 8500
      discovery:
        service-name: ${spring.application.name}

#secondProject的Yml---------------------------
server:
  port: 5002
spring:
  application:
    name: secondProject #注册到zk的消费者名称
  zipkin:
    base-url: http://10.20.30.94:9411
  sleuth:
    sampler:
      #采样率值介于 0 到 1 之间,1 则表示全部采集
      probability: 1
  cloud:
    consul:
      host: 10.20.30.94:8500
      port: 8500
      discovery:
        service-name: ${spring.application.name}

#thirdProject的Yml---------------------------
server:
  port: 5003
spring:
  application:
    name: thirdProject #注册到zk的消费者名称
  zipkin:
    base-url: http://10.20.30.94:9411
  sleuth:
    sampler:
      #采样率值介于 0 到 1 之间,1 则表示全部采集
      probability: 1
  cloud:
    consul:
      host: 10.20.30.94:8500
      port: 8500
      discovery:
        service-name: ${spring.application.name}


三个项目的启动类

//firstProject的---------------------------
package com.rb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FirstProjectApplication {
    public static void main(String[] args) {
        SpringApplication.run(FirstProjectApplication.class,args);
    }
}

//secondProject的---------------------------
package com.rb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class SecondProjectApplication {
    public static void main(String[] args) {
        SpringApplication.run(SecondProjectApplication.class,args);
    }
}

//thirdProject的---------------------------
package com.rb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class ThirdProjectApplication {
    public static void main(String[] args) {
        SpringApplication.run(ThirdProjectApplication.class,args);
    }
}

三个项目的配置类

package com.rb.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class ApplicationContextBean
{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}

三个项目的Controller

//firstProject的---------------------------
package com.rb.controller;

import brave.Tracer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class FirstController {
    public static final String URL = "http://secondProject";
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private Tracer tracer;

    @GetMapping("/first/getMethod")
    public String getMethod(String val){
        String result = restTemplate.getForObject(URL+"/second/getMethod?val="+val, String.class);
        return result;
    }
}
//secondProject的---------------------------
package com.rb.controller;

import brave.Tracer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class SecondController {
    public static final String URL = "http://thirdProject";
    @Autowired
    private RestTemplate restTemplate;
    @Autowired
    private Tracer tracer;

    @GetMapping("/second/getMethod")
    public String getMethod(String val){
        String result = restTemplate.getForObject(URL+"/third/getMethod?val="+val, String.class);
        return result;
    }
}
//thirdProject的---------------------------
package com.rb.controller;

import brave.Tracer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class ThirdController {
    @Autowired
    private Tracer tracer;
    @GetMapping("/third/getMethod")
    public String getMethod(String val){
        return val;
    }
}

测试

  1. 启动三个项目,然后访问firstProject

127.0.0.1:5001/first/getMethod?val=customer1234

  1. 打开ZipKin,即可查到对应的调用链路

其他

通过代码中注入Tracer类,可获得调用Span ID或Trace ID

    @Autowired
    private Tracer tracer;

    @GetMapping("/first/getMethod")
    public String getMethod(String val){
        Span span = tracer.currentSpan();
        String traceId = span.context().traceIdString();//获得traceId
        String spanId = span.context().spanIdString();//获得spanId
        span.tag("MyParameter",val);//将入参传入,可通过ZipKin查看
        String result = restTemplate.getForObject(URL+"/second/getMethod?val="+val, String.class);
        return result;
    }

在ZipKin查看自定义的参数

上面代码自定义了一个“MyParameter”,发起请求后,打开Zipkin,找到对应链路后在此处查看

image-20230217182349270

posted @ 2023-02-17 18:25  RollBack2010  阅读(53)  评论(0编辑  收藏  举报