spring cloud Greenwich 学习笔记(十)spring cloud sleuth 服务链路追踪

springcloud系列学习笔记目录参见博主专栏 spring boot 2.X/spring cloud Greenwich
由于是一系列文章,所以后面的文章可能会使用到前面文章的项目。文章所有代码都已上传GitHub:https://github.com/liubenlong/springcloudGreenwichDemo
本系列环境:Java11;springboot 2.1.1.RELEASE;springcloud Greenwich.RELEASE;MySQL 8.0.5;

概述

目前主流的分布式微服务系统都会有大量的服务,各个服务之间会有相互的调用,问题排查起来比较困难,不容易定位。这时就需要分布式服务全链路追踪体系。

Google开源的 Dapper链路追踪组件,并在2010年发表了论文《Dapper, a Large-Scale Distributed Systems Tracing Infrastructure》,这篇文章是业内实现链路追踪的标杆和理论基础,具有非常大的参考价值。
目前,链路追踪组件有Google的Dapper,Twitter 的Zipkin,以及阿里的Eagleeye (鹰眼)等,它们都是非常优秀的链路追踪开源组件。

Spring Cloud Sleuth是Spring Cloud的分布式跟踪工具。 本文将介绍Spring Cloud Sleuth与zipkin集成。

本文内容主要参考:Spring Cloud Sleuth官网

Spring Cloud Sleuth基本术语

Spring Cloud Sleuth采用的是Google的开源项目Dapper的专业术语。

Span:基本工作单元,发送一个远程调度任务 就会产生一个Span,Span是一个64位ID唯一标识的,Trace是用另一个64位ID唯一标识的,Span还有其他数据信息,比如摘要、时间戳事件、Span的ID、以及进度ID。
Trace:一系列Span组成的一个树状结构。请求一个微服务系统的API接口,这个API接口,需要调用多个微服务,调用每个微服务都会产生一个新的Span,所有由这个请求产生的Span组成了这个Trace。
Annotation:用来及时记录一个事件的,一些核心注解用来定义一个请求的开始和结束 。这些注解包括以下:

  • cs - Client Sent -客户端发送一个请求,这个注解描述了这个Span的开始
  • sr - Server Received -服务端获得请求并准备开始处理它,如果将其sr减去cs时间戳便可得到网络传输的时间。
  • ss - Server Sent (服务端发送响应)–该注解表明请求处理的完成(当请求返回客户端),如果ss的时间戳减去sr时间戳,就可以得到服务器请求的时间。
  • cr - Client Received (客户端接收响应)-此时Span的结束,如果cr的时间戳减去cs时间戳便可以得到整个请求所消耗的时间。
    在这里插入图片描述
    上图中每个颜色的表明一个span(总计7个spans,从A到G),每个span有类似的信息
Trace Id = X
Span Id = D
Client Sent

该span表示span的Trance Id是X,Span Id是D,同时它发送一个Client Sent事件
下图展示了span的父子关系:
在这里插入图片描述

使用官方jar包启动zipkin服务(推荐)

准备zipkin

zipkin官网下载页 下载zipkin zipkin-server-2.10.1-exec.jar。我这里下载的是2.10.1版本。最新版的2.12.1版本无法展示依赖关系,可能有不兼容的地方。
下载完成后启动接口,默认端口是9411
java -jar zipkin-server-2.10.1-exec.jar

springcloud集成zipkin

本节内容在springcloud-eureka-serverspringcloud-eureka-serviceconsumer-feignspringcloud-eureka-serviceprovider三个系统中完成。
springcloud-eureka-server系统不需要改动,直接启动即可。
改造springcloud-eureka-serviceprovider系统,添加zipkin依赖

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

配置文件中添加zipkin的配置:

spring:
  application:
    name: springcloud-eureka-serviceprovider
  zipkin:
    base-url: http://localhost:9411

改造之前controller的hi方法:

private static final Logger LOG = Logger.getLogger(Application.class.getName());

@RequestMapping("/")
public String hi(String name) {
    LOG.log(Level.INFO, "info is being called");
    return String.format("hello %s , from port=%s", name, port);
}

springcloud-eureka-serviceprovider改造完成,启动即可。
接下来改造springcloud-eureka-serviceconsumer-feign,同理先添加zipkin的pom依赖,与之前一样。
然后在配置文件中添加zipkin的配置

# 服务与服务之间相互调用一般都是根据这个name 。
spring:
  application:
    name: springcloud-eureka-serviceconsumer-feign
  zipkin:
    base-url: http://localhost:9411

改造原有的HelloController :

@RestController
public class HelloController {
    private static final Logger LOG = Logger.getLogger(HelloController.class.getName());
    
    @Autowired
    HelloService helloService;

    @RequestMapping("/")
    public String hi(String name) {
        LOG.log(Level.INFO, "calling trace service-hi  ");
        //这里直接写的是服务名: springcloud-eureka-serviceprovider  。在ribbon中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的url替换掉服务名
        return helloService.hi(name);
    }
}

启动springcloud-eureka-serviceconsumer-feign项目。

注:上面两个工程都需要添加Logger日志,否则无法进行追踪管理。

OK,到这里所有准备工作完成。

运行测试

访问http://127.0.0.1:8080/可以看到注册到上面的服务

在这里插入图片描述
访问http://127.0.0.1:8086/?name=z成功后,进入到http://localhost:9411zipkin的管理页面,点击find traces会看到刚才 的请求:
在这里插入图片描述
点击该条请求进入,会看的服务调用链路信息,以及所消耗的时间,通过这个时间可以有针对性的进行系统性能调优:
在这里插入图片描述
然后点击依赖分析,会看到系统的调用关系图。
在这里插入图片描述

其他相关文章: spring boot 2.1学习笔记【十二】SpringBoot 2 集成 dubbo 2.6.5 最后一节介绍了dubbo+MDC实现的分布式日志追踪。

自己搭建zipkin服务

搭建springcloud-zipkin-server项目

这里我们使用自己搭建的springcloud-zipkin-server项目来替换上面的zipkin-server-2.10.1-exec.jarjar包。这种方式更加灵活,可以对其进行一些额外的配置。

首先引入依赖

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-server</artifactId>
    <version>2.10.1</version>
</dependency>
<dependency>
    <groupId>io.zipkin.java</groupId>
    <artifactId>zipkin-autoconfigure-ui</artifactId>
    <version>2.10.1</version>
</dependency>

配置文件:

server:
  port: 9411

# 最佳实践:springcloud应用都要指定application.name
spring:
  application:
    name: springcloud-zipkin-server
  main:
    allow-bean-definition-overriding: true # 当bean重复定义时允许相同key情况下beanDefinition实例的覆盖

eureka:
  client:
    serviceUrl:
      #      指定服务注册中心的地址
      defaultZone: http://localhost:8080/eureka/
#      上面是eureka单机注册中心。下面是eureka集群模式
#      defaultZone: http://admin:123456@eureka2:8001/eureka/,http://admin:123456@eureka3:8002/eureka/,http://admin:123456@eureka2:8003/eureka/

main方法:

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

至此,springcloud-zipkin-server项目搭建完成。
依次启动服务:springcloud-eureka-server,springcloud-zipkin-server,springcloud-eureka-serviceprovider,springcloud-eureka-serviceconsumer-feign。访问http://127.0.0.1:8086/?name=abcx接口,既可以在zipkin的web页面上查询相关追踪日志了。
在这里插入图片描述

spring.main.allow-bean-definition-overriding

大家可以看到,在上面的配置文件中配置了setting spring.main.allow-bean-definition-overriding=true
如果不进行配置,会报错:


The bean 'characterEncodingFilter', defined in class path resource [zipkin/autoconfigure/ui/ZipkinUiAutoConfiguration.class], could not be registered. A bean with that name has already been defined in class path resource [org/springframework/boot/autoconfigure/web/servlet/HttpEncodingAutoConfiguration.class] and overriding is disabled.
Action:

Consider renaming one of the beans or enabling overriding by setting spring.main.allow-bean-definition-overriding=true

从错误信息中可以看到,characterEncodingFilter这个bean被定义了两次,ZipkinUiAutoConfiguration和HttpEncodingAutoConfiguration都有定义。在大型项目开发过程中,这种情况并不少见。毕竟各个不同的组件都是独立开发的,集成到一起后总会遇到各种惊喜。spring.main.allow-bean-definition-overriding=true就是解决bean重复定义的。设置为true时,后定义的bean会覆盖之前定义的相同名称的bean

关于spring.main.allow-bean-definition-overriding的源码解析请参考本人另一篇博客:spring中 allowBeanDefinitionOverriding(spring.main.allow-bean-definition-overriding) 分析

springcloud系列学习笔记目录参见博主专栏 spring boot 2.X/spring cloud Greenwich
由于是一系列文章,所以后面的文章可能会使用到前面文章的项目。文章所有代码都已上传GitHub:https://github.com/liubenlong/springcloudGreenwichDemo
本系列环境:Java11;springboot 2.1.1.RELEASE;springcloud Greenwich.RELEASE;MySQL 8.0.5;

展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: Age of Ai 设计师: meimeiellie
应支付0元
点击重新获取
扫码支付

支付成功即可阅读