SPRING CLOUD微服务实战笔记--分布式服务跟踪:Spring Cloud Sleuth

拼搏现实的明天。 2022-02-24 06:57 440阅读 0赞

Spring Cloud Sleuth

  • 快速入门
    • 准备工作
    • 实现跟踪
  • 跟踪原理
  • 与Logstash整合
  • 与ZipKin整合
    • HTTP收集
    • 消息中间件收集
    • 数据存储

快速入门

准备工作

  • 服务注册中心:eureka-server,可以直接使用之前的工程
  • 微服务应用:trace-1,实现一个REST接口/trace-1,调用该接口后将触发对trace-2应用的调用
    具体实现如下:
    1)创建一个基础的Spring Boot应用,在pom.xml中增加依赖:



    org.springframework.cloud
    spring-cloud-starter-eureka
    1.4.6.RELEASE


    org.springframework.boot
    spring-boot-starter-web


    org.springframework.cloud
    spring-cloud-starter-ribbon
    1.4.6.RELEASE


    org.springframework.boot
    spring-boot-starter-test
    test

2)创建主类,实现/trace-1接口,并使用RestTemplate调用trace-2应用的接口

  1. @RestController
  2. @EnableEurekaClient
  3. @SpringBootApplication
  4. public class HelloApplication {
  5. private final Logger logger = LoggerFactory.getLogger(getClass());
  6. @Bean
  7. @LoadBalanced
  8. RestTemplate restTemplate(){
  9. return new RestTemplate();
  10. }
  11. @RequestMapping(value = "/trace-1",method = RequestMethod.GET)
  12. public String trace(){
  13. logger.info("===call trace-1====");
  14. return restTemplate().getForEntity("http://trace-2/trace-2",String.class).getBody();
  15. }
  16. public static void main(String[] args) {
  17. SpringApplication.run(HelloApplication.class, args);
  18. }
  19. }

3)在application.properties中,将eureka.client.serviceUrl.defaultZone参数指向eureka-server地址

  1. spring.application.name=trace-1
  2. server.port=9101
  3. eureka.client.service-url.defaultZone=http://localhost:1111/eureka
  • 微服务应用:trace-2,实现一个REST接口/trace-2,供trace-1调用
    1)创建一个基础的SpringBoot应用,pom.xml的依赖与trace-1相同
    2)创建应用主类,并实现/trace-2接口,具体如下:

    @RestController
    @EnableEurekaClient
    @SpringBootApplication
    public class HelloApplication {
    private final Logger logger = LoggerFactory.getLogger(getClass());
    @RequestMapping(value = “/trace-2”,method = RequestMethod.GET)
    public String trace(){

    1. logger.info("===<call trace-2>====");
    2. return "Trace";

    }
    public static void main(String[] args) {

    1. SpringApplication.run(HelloApplication.class, args);

    }
    }

3)在application.properties中,将eureka.client.serviceUrl.defaultZone参数指向eureka-server地址,并设置不同的应用名与端口

  1. spring.application.name=trace-2
  2. server.port=9102
  3. eureka.client.service-url.defaultZone=http://localhost:1111/eureka
  • 启动eureka-server,trace-1,trace-2三个应用,发送请求http://localhost:9101/trace-1,可以看到返回值Trace,同时trace-1控制台打印===call trace-1====,trace-2控制台打印===<call trace-2>====

实现跟踪

在trace-1和trace-2的pom.xml依赖管理中增加spring-cloud-starter-sleuth依赖即可

  1. <dependency>
  2. <groupId>org.springframework.cloud</groupId>
  3. <artifactId>spring-cloud-starter-sleuth</artifactId>
  4. <version>1.3.5.RELEASE</version>
  5. </dependency>

重启trace-1和trace-2后,控制台打印发生变化,

  1. INFO [trace-1,ddcf47da76da68c7,ddcf47da76da68c7,false] 70283 --- [nio-9101-exec-1] ication$$EnhancerBySpringCGLIB$$84347891 : ===call trace-1====
  2. INFO [trace-2,ddcf47da76da68c7,248958640a14c496,false] 70280 --- [nio-9102-exec-1] ication$$EnhancerBySpringCGLIB$$84347891 : ===<call trace-2>====

可以看到增加了[trace-2,ddcf47da76da68c7,ddcf47da76da68c7,false]类似的日志信息,含义如下:

  • 第一个值:trace-1,记录应用的名称
  • 第二个值:ddcf47da76da68c7,Spring Cloud Sleuth生成的一个ID,成为TraceID,用来标识一条请求链路。一条请求链路包含一个TraceId
  • 第三个值:248958640a14c496,Spring Cloud Sleuth生成的另一个ID,成为Span ID,表示一个基本的工作单元,比如发送一个HTTP请求
  • 第四个值:false,表示是否要将该信息输出到Zipkin等服务中来收集和展示
    在一次服务请求链路的调用过程中,会保持并传递同一个Traceid,从而将整个分布于不同微服务进程中的请求跟踪信息串联起来。如上面例子,trace-1与trace-2同属于一个前端服务请求来源,所以它们的TraceID相同,处于同一条请求链路中。

跟踪原理

TraceID和SpanID是Spring Cloud Sleuth实现分布式服务跟踪的核心

  • 通过唯一跟踪标识TraceID的记录,能将所有请求过程的日志关联起来
  • SpanID可以统计各处理单元的时间延迟,还可以包含一些其他数据,比如事件名称,请求信息等
    spring-cloud-starter-sleuth组件在转发请求的Header中增加实现跟踪需要的重要信息,主要有下面几个:
  • X-B3-TraceId:一条请求链路(Trace)的唯一标识,必需的值
  • X-B3-SpanId:一个工作单元(Span)的唯一标识,必需的值
  • X-B3-ParentSpanId:标识当前工作单元所属的上一个工作单元,RootSpan(请求链路的第一个工作单元)的该值为空
  • X-Span-Name:工作单元的名称
    1.对trace-1和trace-2的实现进行修改

    @RequestMapping(value = “/trace-1”,method = RequestMethod.GET)

    1. public String trace(HttpServletRequest request){
    2. logger.info("====<call trace-1>=====,TraceId={},SpanId={},ParentSpanId={},Sampled={},SpanName={}"
    3. ,request.getHeader("X-B3-TraceId"),request.getHeader("X-B3-SpanId")
    4. ,request.getHeader("X-B3-ParentSpanId"),request.getHeader("X-B3-Sampled"),request.getHeader("X-Span-Name"));
    5. return restTemplate().getForEntity("http://trace-2/trace-2",String.class).getBody();
    6. }

    @RequestMapping(value = “/trace-2”,method = RequestMethod.GET)

    1. public String trace(HttpServletRequest request){
    2. logger.info("====<call trace-2>=====,TraceId={},SpanId={},ParentSpanId={},Sampled={},SpanName={}"
    3. ,request.getHeader("X-B3-TraceId"),request.getHeader("X-B3-SpanId")
    4. ,request.getHeader("X-B3-ParentSpanId"),request.getHeader("X-B3-Sampled"),request.getHeader("X-Span-Name"));
    5. return "Trace";
    6. }

2.在trace-1和trace-2的application.properties中加入配置,可以更加直观的观察跟踪信息

  1. logging.level.org.springframework.web.servlet.DispatcherServlet=debug

重启trace-1和trace-2的应用,可以看到
trace-1的控制台
trace-1
trace-2的控制台
trace-2
trace-2中的ParentSpanId就是trace-1中的SpanId,trace-2中的TraceId与trace-1中的TraceId相同

与Logstash整合

由于日志文件都离散地存储在各个服务实例的文件系统之上,引入基于日志的分析系统是一个不错的选择,比如ELK平台,它可以轻松地收集和存储跟踪日志,同时还可以根据TraceId搜索出对应请求链路相关的明细日志
ELK平台主要由ElasticSearch、Logstash和Kibana三个工具组成

  • ElasticSearch是一个开源分布式搜索引擎,它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,RESTful风格接口,多数据源,自动搜索负载等
  • Logstash是一个完全开源的工具,它可以对日志进行收集、过滤,并将其存储供以后使用
  • Kibana也是一个开源和免费的工具,可以为Logstash和ElasticSearch提供日志分析友好的Web界面,可以帮助汇总、分析和搜索重要数据日志
    如何实现面向Logstash的日志输出配置
  • 在pom.xml中新增依赖


    net.logstash.logback
    logstash-logback-encoder
    4.6
  • 在工程/resource目录下创建bootstrap.properties配置,并将spring.application.name=trace-1加到配置中

  • 在工程/resource目录下创建logback配置文件logback-spring.xml

与ZipKin整合

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

HTTP收集

第一步:搭建Zipkin Server

  • 创建一个基础的SpringBoot应用,命名为zipkin-server,并修改pom.xml引入依赖


    io.zipkin.java
    zipkin-server
    2.0.1



    io.zipkin.java
    zipkin-autoconfigure-ui
    2.0.1
  • 创建应用主类,使用@EnableZipkinServer注解来启动ZipkinServer,具体如下:

    @EnableZipkinServer
    @SpringBootApplication
    public class HelloApplication {

    1. public static void main(String[] args) {
    2. SpringApplication.run(HelloApplication.class, args);
    3. }

    }

  • 修改application.properties中的配置

    spring.application.name=zipkin-server
    server.port=9411

创建完成后,启动工程,并访问http://localhost:9411/,可以看到如下Zipkin管理页面:
Zipkin
第二步:为应用引入和配置Zipkin服务
在完成了Zipkin Server的搭建之后,还需要对应用做一些配置,以实现将跟踪信息输出到Zipkin Server。

  • 在trace-1和trace-2的pom.xml中引入spring-cloud-sleuth-zipkin依赖,具体如下所示:


    org.springframework.cloud
    spring-cloud-sleuth-zipkin
    1.3.5.RELEASE
  • 在trace-1和trace-2的application.properties中增加Zipkin Server的配置信息。

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

重启eureka-server、trace-1、trace-2,发送请求http://localhost:9101/trace-1,可以查询出在日志中出现的跟踪信息
Find Traces
单击每一条记录,还能看到具体的跟踪信息
跟踪信息

消息中间件收集

第一步:修改客户端trace-1 和trace-2

  • 修改客户端的pom.xml,引入


    org.springframework.cloud
    spring-cloud-starter-sleuth
    1.3.5.RELEASE




    org.springframework.cloud
    spring-cloud-sleuth-stream
    1.3.5.RELEASE


    org.springframework.cloud
    spring-cloud-starter-stream-rabbit
    1.3.4.RELEASE
  • application.properties配置修改,增加消息中间件的相关配置

    spring.rabbitmq.host=localhost
    spring.rabbitmq.port=5672
    spring.rabbitmq.username=springcloud
    spring.rabbitmq.password=123456

第二步:修改zipkin-server服务端

  1. <dependencies>
  2. <dependency>
  3. <groupId>io.zipkin.java</groupId>
  4. <artifactId>zipkin-server</artifactId>
  5. <version>2.0.1</version>
  6. </dependency>
  7. <dependency>
  8. <groupId>io.zipkin.java</groupId>
  9. <artifactId>zipkin-autoconfigure-ui</artifactId>
  10. <version>2.0.1</version>
  11. </dependency>
  12. <dependency>
  13. <groupId>org.springframework.cloud</groupId>
  14. <artifactId>spring-cloud-sleuth-zipkin-stream</artifactId>
  15. <version>1.3.5.RELEASE</version>
  16. </dependency>
  17. <dependency>
  18. <groupId>org.springframework.cloud</groupId>
  19. <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
  20. <version>1.3.4.RELEASE</version>
  21. </dependency>
  22. </dependencies>
  • 重新启动eureka-server、trace-1、trace-2、zipkin-server,同时确保RabbitMQ也处于运行状态,可以在RabbitMQ的管理页面看到一个名为sleuth的交换器
    通过向trace-1的接口发送几个请求http://localhost:9101/trace-1,可以看到管理页面中的统计曲线变化
    sleuth

数据存储

默认情况下,Zipkin Server会将跟踪信息存储在内存中,一方面每次重启Zipkin Server都会使之前收集的跟踪信息丢失,另一方面当有大量跟踪信息时内存存储会成为瓶颈,所以通常情况下都会将跟踪信息对接到外部存储组件中去,比如使用MySQL存储

发表评论

表情:
评论列表 (有 0 条评论,440人围观)

还没有评论,来说两句吧...

相关阅读