springcloud微服务分布式链路追踪之zipkin实战教程

本文主要是介绍springcloud微服务分布式链路追踪之zipkin实战教程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

简介
  • 微服务实施的过程一般会进行细粒度的拆分,服务不允许跨库访问,每个微服务全权负责自己的业务领域。但是很多时候一个功能接口需要多个服务互相配合才能完成,这里自然就会用到服务间的调用和依赖关系。往往这种依赖关系随着业务和系统的演进,即使是资深的架构师也很难清楚的画出一份服务调用关系图来。而Spring Cloud Sleuth为Spring Cloud实现了分布式链路跟踪解决方案。

本文将介绍其springcloudsleuth整合zipkin来作为系统的链路追踪工具,内容有

  • 链路追踪调用链信息术语介绍
  • 搭建链路追踪服务器
  • 微服务集成链路追踪客户端进行调用信息收集
  • 链路追踪信息采样频率使用说明
  • 集成链路追踪调用链生成插件,生成系统调用链关系图

原文:传送门

注:本文基于springcloud2.1.3 Greenwich.RELEASE 版本

参考文章
  • Spring Cloud Sleuth官方使用教程
  • zipkin-dependencies使用介绍

1、链路追踪调用链信息术语介绍

Span

Span是基本的工作单元。Span包括一个64位的唯一ID,一个64位trace码,描述信息,时间戳事件,key-value 注解(tags),span处理者的ID(通常为IP)。
最开始的初始Span称为根span,此span中span id和 trace id值相同。

  • 个人对span的解读

    span可以分为两类:

    • 一类是描述服务内部处理这个接口的过程
    • 另一类是描述服务间的一次调用过程

    举个栗子,client需要调用service1的一个接口,service1又要调用service2的某个接口。

    步骤如下:

    1. service1接收到client的请求(sr),span1
    2. service1需要调用service2的某个接口(cs),span2
    3. service2接收到service1的请求(sr),span2
    4. service2处理接口逻辑,(内部处理过程) span3
    5. service2返回接口响应给service1(ss),span2
    6. service1接收到service2的响应结果(cr),span2
    7. service1再处理完该接口内的内部逻辑,(内部处理过程) span4
    8. service1再返回给client(ss)。span1

    这里就可以分析出

    • span1描述了client–>service1之间的调用过程
    • span2描述了service1–>service2之间的调用过程
    • span3描述了service2自己的业务逻辑处理过程
    • span4描述了service1的内部处理过程

Trance

包含一系列的span,它们组成了一个树型结构。从客户发起请求(request)抵达被追踪系统的边界开始,到被追踪系统向客户返回响应(response)为止的整个过程

Annotation

用于及时记录存在的事件。常用的Annotation如下

  • cs - Client Sent:客户端发送一个请求,表示span的开始

  • sr - Server Received:服务端接收请求并开始处理它。(sr-cs)等于网络的延迟

  • ss - Server Sent:服务端处理请求完成,开始返回结束给服务端。(ss-sr)表示服务端处理请求的时间

  • cr - Client Received:客户端完成接受返回结果,此时span结束。(cr-sr)表示客户端接收服务端数据的时间
    如果一个服务的调用关系如下:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-x2IOnJ2n-1584002254359)(http://www.danyuanblog.com/file-gateway//ueditor/jsp/upload/image/20191026/1572066157023046128.png)]
    那么此时将Span和Trace在一个系统中使用Zipkin注解的过程图形化:
    调用链过程分解图

每个颜色的表明一个span(总计7个spans,从A到G),每个span有类似的信息

Trace Id = X  #调用链ID,用来标识同一个请求
Span Id = D #调用链中的一个步骤,用来描述接口处理的过程
Client Sent  #服务间的调用类型的span的调用过程各个阶段的描述,所以只有服务间调用的span才存在此信息

此span表示span的Trance Id是X,Span Id是D,同时它发送一个Client Sent事件

  • 该调用链中各个span之间的关系图如下所示:
    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K2Hg8rZV-1584002254360)(http://www.danyuanblog.com/file-gateway//ueditor/jsp/upload/image/20191026/1572066197284006549.png)]
    调用链中各个span的说明
    在Zipkin中展示了上图的跟踪信息,红框里是对上图调用span的跟踪

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6OnfzIJj-1584002254361)(http://www.danyuanblog.com/file-gateway//ueditor/jsp/upload/image/20191026/1572066497886050473.png)]

但是你点击这个trace时,我们只看到4个span

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WUFzb1OO-1584002254363)(http://www.danyuanblog.com/file-gateway//ueditor/jsp/upload/image/20191026/1572066514925091210.png)]

为什么两个界面显示的span数量不同,一个是7,一个4.

  • 1 个 spans:来自servier1的接口http:/start 被调用,分别是Server Received (SR) 和 Server Sent (SS) annotations.
  • 2 个 spans:来自 service1 调用service2 的 http:/foo 接口。service1 端有两个span,分别为 Client Sent (CS) 和 Client Received (CR) annotations。service2 端也有两个span,分别为Server Received (SR) 和Server Sent (SS) 。物理上他有2个span,但是从逻辑上说这个他们组成一个RPC调用的span。
  • 2个span:来自 service2 调用 service3 的 http:/bar 接口,service2 端有两个span,分别为Client Sent (CS) 和 Client Received (CR) annotations。service3 端也有两个span,分别为Server Received (SR) 和Server Sent (SS) 。物理上他有2个span,但是从逻辑上说它们都是同一个RPC调用的span。
  • 2个span:来自 service2 调用 service4 的 http:/bar 接口,service2 端有两个span,分别为Client Sent (CS) 和 Client Received (CR) annotations。service4 端也有两个span,分别为Server Received (SR) and Server Sent (SS) 。物理上他有2个span,但是从逻辑上说这个它们都是同一个RPC调用的span。

所以我们计算物理spans有7个:

  • 1个来自 http:/start 被请求

  • 2个来自 service1调用service2

  • 2个来自 service2调用service3

  • 2个来自 service2调用service4.
    从逻辑上说,我们只看到4个span:

  • 1个来自client发起的接口调用

  • 3个来自服务之间的接口调用

总结:物理span包含了服务内部处理逻辑span和服务间接口调用过程描述span,逻辑span只记录了服务间接口调用过程描述的span。

2、搭建链路追踪服务器
2.1 简介

链路追踪服务将整合zipkin作为链路追踪日志收集服务器,功能特性说明

  • 存储组件为Elasticsearch
  • 日志收集方式为RabbitMq异步收集
  • 配置信息会用到springcloudconfig
  • 注册到Eureka注册中心,启用服务发现功能
2.2 pom.xml引入依赖
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.danyuanblog.springcloud</groupId><artifactId>spring-cloud-zipkin-server</artifactId><name>spring-cloud-zipkin-server</name><url>http://www.danyuanblog.com</url><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.1.3.RELEASE</version><relativePath /> <!-- lookup parent from repository --></parent><!-- 定义公共变量 --><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><java.version>1.8</java.version><spring-cloud.version>Greenwich.RELEASE</spring-cloud.version><zipkin-server.version>2.11.8</zipkin-server.version>  <zipkin-es.version>2.8.4</zipkin-es.version>  </properties><dependencies><!-- Eureka注册中心客户端依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency><!-- 链路追踪相关依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId></dependency><!-- zipkin服务器依赖 --><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-server</artifactId><version>${zipkin-server.version}</version><exclusions><exclusion><artifactId>spring-boot-starter-log4j2</artifactId><groupId>org.springframework.boot</groupId></exclusion></exclusions></dependency> <!-- zipkin管理后台依赖 --><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-ui</artifactId><version>${zipkin-server.version}</version></dependency><!-- zipkin 整合Elasticsearch存储组件依赖 --><!-- https://mvnrepository.com/artifact/io.zipkin.java/zipkin-autoconfigure-storage-elasticsearch-http --><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-storage-elasticsearch-http</artifactId><version>${zipkin-es.version}</version></dependency><!-- zipkin使用rabbitmq异步收集调用链信息依赖 --><dependency><groupId>io.zipkin.java</groupId><artifactId>zipkin-autoconfigure-collector-rabbitmq</artifactId><version>2.11.8</version></dependency><dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-stream-rabbit</artifactId> </dependency> <!-- 配置中心客户端依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-config</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency><!-- 连接配置中心重试的依赖 --><dependency><groupId>org.springframework.retry</groupId><artifactId>spring-retry</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-bus-amqp</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency></dependencies><repositories><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url></repository><repository><id>Sonatype</id><name>Sonatype Repository</name><url>http://repository.sonatype.org/content/groups/public</url><layout>default</layout><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository><repository><id>Central</id><name>Central Repository</name><url>http://repo1.maven.org/maven2</url><layout>default</layout><releases><enabled>true</enabled></releases><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><name>oss.sonatype.org</name><id>oss.sonatype.org</id><url>http://oss.sonatype.org/content/groups/public</url></pluginRepository></pluginRepositories>
</project>
2.3 编辑启动类StartZipkinApplication.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;import zipkin2.server.internal.EnableZipkinServer;@EnableZipkinServer
@EnableDiscoveryClient
@SpringBootApplication
public class StartZipkinApplication {public static void main(String[] args) {SpringApplication.run(StartZipkinApplication.class, args);}	
}
2.3 配置信息
  • 编辑bootstrap.yml
spring:application:name: zipkin-servercloud:#配置中心客户端信息config:discovery:enabled: trueservice-id: config-server      label: master    fail-fast: trueretry:initial-interval: 2000        #首次重试间隔时间,默认1000毫秒multiplier: 1.1D              #下一次重试间隔时间的乘数,比如开始1000,下一次就是1000*1.1=1100max-interval: 2000            #最大重试时间,默认2000max-attempts: 20               #最大重试次数,默认6次
#注册中心客户端信息  
eureka:client: serviceUrl: defaultZone: http://localhost:8763/eureka/instance:prefer-ip-address: trueleaseRenewalIntervalInSeconds: 10health-check-url-path: /actuator/healthserver:port: 9411
  • 编辑zipkin-server.yml
maxHttpHeaderSize: 8192
spring:sleuth:enabled: false
#采样率,推荐0.1,百分之百收集的话存储可能扛不住sampler:percentage: 1 #100%采集用于测试
zipkin: collector:rabbitmq:addresses: localhostport: 5672username: adminpassword: adminqueue: zipkinstorage: type: elasticsearch #es存储zipkin追踪信息StorageComponent: elasticsearchelasticsearch:hosts: localhost:9200cluster: elasticsearchindex: zipkinindex-shards: 5index-replicas: 1      
3、微服务集成链路追踪客户端进行调用信息收集
3.1 功能说明

微服务也需要注册到Eureka注册中心,便于使用服务发现功能

  • 链路追踪信息收集功能只依赖于zipkin-server服务名,便于zipkin-server做集群化
  • 信息收集采用rabbitmq异步收集
3.2 引入maven依赖
		<!-- zipkin链路追踪依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-zipkin</artifactId></dependency><dependency><groupId>org.springframework.amqp</groupId><artifactId>spring-rabbit</artifactId></dependency><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-stream-rabbit</artifactId></dependency>
3.3 配置信息
spring#链路追踪配置zipkin:enabled: true#base-url: http://zipkin-server/ #采用MQ方式收集便不用配置zipkin服务器信息了rabbitmq:queue: zipkinlocator:discovery:enabled: truesender:type: rabbitmqsleuth:sampler:#采样率,推荐0.1,百分之百收集的话存储可能扛不住probability: 1.0  
4、链路追踪信息采样频率使用说明

spring.sleuth.sampler.probability用于设置链路追踪信息采样率

  • 测试环境建议配置为1,表示100%收集
  • 线上根据实际用户量来配置,如果接口并发比较高,0.1就足够反应整个平台的服务链路情况了
5、集成链路追踪调用链生成插件,生成系统调用链关系图
  • 下载依赖包
curl -sSL https://zipkin.io/quickstart.sh | bash -s io.zipkin.dependencies:zipkin-dependencies:LATEST zipkin-dependencies.jar
  • 每天定时生成调用链依赖关系图
#生成当前时间前一天的调用链依赖关系图
STORAGE_TYPE=elasticsearch ES_HOSTS=localhost:9200 ES_INDEX=zipkin java -jar zipkin-dependencies.jar `date -u -d '1 day ago' +%F`

然后进入zipkin-server管理后台,进入Dependencies菜单,选择对应的日期范围

  • 生成的调用链关系图是根据接口的实际调用情况绘制而成
  • 线条越粗代表调用量越大

这篇关于springcloud微服务分布式链路追踪之zipkin实战教程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1054713

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件