SpringCloud集成Sleuth+Zipkin进行链路追踪

news2024/11/25 16:48:01

关于微服务链路追踪的一些概念:【分布式链路追踪】

文章目录

  • 1、整合Seluth
  • 2、日志信息分析
  • 3、Zipkin介绍
  • 4、Zipkin服务端安装
  • 5、搭配Sleuth整合客户端Zipkin
  • 6、收集数据
  • 7、存储trace数据

1、整合Seluth

Spring Cloud Sleuth是一个用于追踪的工具,它可以将微服务调用的追踪信息(trace ID、parent ID、span ID、timestamp等)进行收集和传输

  • 微服务的pom.xml中引入Sleuth依赖
<!--sleuth链路追踪-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-sleuth</artifactId>
    <version>2.2.0.RELEASE</version>
</dependency>

  • 在微服务的配置文件application.yml中添加日志级别
logging:
	level:
		org.springframework.cloud.sleuth: DEBUG
  • 重启服务,调用相关接口,查看控制台输出

在这里插入图片描述

2、日志信息分析

在这里插入图片描述

  • 方括号[ ]中的两个数字,第一个是traceID,后面的是spanID
  • 一次调用有一个全局的traceID
  • 后面的true,和抽样比例有关,为false时,不会被后面的zipkin处理

使用traceID和spanID将整个链路串起来,就是请求的具体过程,但当调用关系复杂时,这样查看日志,效率太低了。因此,可使用Zipkin将日志信息进行聚合,然后进行一个可视化的展示和全文检索。

3、Zipkin介绍

Zipkin 是 Twitter 的一个开源项目,基于 Google Dapper 实现,致力于收集服务的定时数据,以解决微服务架构中的延迟问题,包括数据的收集、存储、查找和展现。

# 官方文档
https://zipkin.io/pages/quickstart

在这里插入图片描述
Zipkin的架构中,有四大块:

  • Controller:收集器,处理从外部系统发送过来的跟踪信息,将这些跟踪信息处理成Zipkin需要的Span格式,以便后面的存储、分析、展示
  • Storage:存储,处理收集器接收到的跟踪信息,默认存于内存,可改为MySQL、ES等
  • RESTful API:API,用来提供外部访问接口,如给客户端展示跟踪信息,或外接系统访问以实现监控
  • Web UI:可视化界面,方便直观地查询和分析跟踪信息

在这里插入图片描述

Zipkin 分为两端,一个是 Zipkin 服务端,一个是 Zipkin 客户端。客户端也就是微服务自身,客户端会配置服务端的 URL 地址,一旦发生服务间的调用的时候,会被配置在微服务里面的 Sleuth 的监听器监听,并生成相应的 Trace 和 Span 数据发送给Zipkin服务端。发送的方式主要有两种,一种是 HTTP 报文的方式,还有一种是消息总线的方式如 RabbitMQ。

4、Zipkin服务端安装

这里可以jar包启动,也可以在容器里启动,具体看官方文档,我采用jar包:

  • 下载编译好的Zipkin-server的jar包
# zipkin-server-2.12.9-exec.jar版本下载
https://search.maven.org/remote_content?g=io.zipkin.java&a=zipkin-server&v=LATEST&c=exec
  • cmd窗口运行jar包
# -Dserver.xxx=xxx参数按需自加
java -jar zipkin-server-2.12.9-exec.jar

在这里插入图片描述

  • 访问localhost:9411查看Zipkin服务端的管理控制台

在这里插入图片描述

5、搭配Sleuth整合客户端Zipkin

前面提到了,仅靠Sleuth收集到的链路日志信息来分析,相当低效,这里继续整合Zipkin来进行链路信息的存储、查找和可视化分析。

  • 需要追踪的微服务中添加Zipkin客户端依赖
<!--zipkin依赖-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
    <version>2.2.0.RELEASE</version>
</dependency>

  • 修改application.yaml配置文件
spring:
  zipkin:
    base-url: http://127.0.0.1:9411/ #zipkin server端的请求地址
    sender:
      type: web #请求方式,默认以http的方式向zipkin server发送追踪数据
  sleuth:
    sampler:
      probability: 1.0 #采样的百分比,默认0.1,即10%,我这里写1,不想调那么多次,就看个效果

  • 重启微服务,调用一次接口,查看Zipkin控制台,点击链路,查看细节

在这里插入图片描述

6、收集数据

在默认情况下,Zipkin客户端和服务端之间是使用HTTP请求的方式进行通信(即同步的请求方式),在网络波动,Server端异常等情况下可能存在信息收集不及时的问题。Zipkin支持与rabbitMQ整合完成异步消息传输。

在这里插入图片描述

  • 起个RabbitMQ的容器,并把端口映射到宿主机上:
docker run -d -p 5672:5672 -p 15672:15672 rabbitmq:3-management
# 访问host:15672,用户和密码为默认的guest

  • 重新启动Zipkin的Server端,这次加参数,指定RabbitMQ的信息
java -jar zipkin-server-2.12.9-exec.jar --RABBIT_ADDRESSES=127.0.0.1:5672

# RABBIT_ADDRESSES : 指定RabbitMQ地址
# RABBIT_USER: 用户名(默认guest)
# RABBIT_PASSWORD : 密码(默认guest)
# 起RabbitMQ容器时我就用默认账户,这里启动Zipkin不再加USER参数
  • 此时登录15672端口查看RabbitMQ,可以看到新多了个队列叫zipkin

在这里插入图片描述

  • 在微服务中整合SpringAMQP,引入依赖:
<!--AMQP依赖,包含RabbitMQ-->
<dependency>
    <groupId>org.springframework.boot</groupId>    		
    <artifactId>spring-boot-starter-amqp</artifactId>
</dependency>

  • 在application.yaml配置文件中配置RabbitMQ的相关信息:
spring:
  rabbitmq:
      host: 192.168.150.101 # MQ服务器主机名
      port: 5672 # 端口
      virtual-host: / # 虚拟主机 
      username: guest # 用户名
      password: guest # 密码
  • 别忘了把zipkin的sender.type改为rabbit,而不是web
spring:
  zipkin:
    # base-url: http://127.0.0.1:9411/ #zipkin server端的请求地址,此时可有可无,
    # 因为client向MQ写,server从MQ拿,启动zipkin时注意关联MQ的信息就行
    sender:
      type: rabbit
  • 接下来做测试,先关闭Zipkin服务端,防止队列中的消息被立马消费,再调用一次微服务的某个接口

在这里插入图片描述

  • 再启动Zipkin的服务端,可以看到MQ中的消息被成功消费:

在这里插入图片描述
在这里插入图片描述

如此,即使Zipkin Server端不可用,或者网络不通,也不会丢失追踪信息。且Client端只要把信息丢MQ就算自己任务完成,耗时缩短。

最后,这里有些坑,比如zipkin队列有了,但是client端不往里面写数据,具体参考这篇:【spring cloud sleuth和zipkin常遇问题及解决方案】

7、存储trace数据

追踪的相关数据,Zipkin服务端默认存于内存中,Service重启或者异常会导致历史追踪数据消息,生产环境中应该将追踪数据持久化到MySQL或者ES中。

  • 这里展示下存储到MySQL,在Zipkin官网复制MySQL建表语句并执行:
/*
SQLyog Ultimate v11.33 (64 bit)
MySQL - 5.5.58 : Database - zipkin
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`zipkin` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `zipkin`;

/*Table structure for table `zipkin_annotations` */

DROP TABLE IF EXISTS `zipkin_annotations`;

CREATE TABLE `zipkin_annotations` (
  `trace_id_high` bigint(20) NOT NULL DEFAULT '0' COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` bigint(20) NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
  `span_id` bigint(20) NOT NULL COMMENT 'coincides with zipkin_spans.id',
  `a_key` varchar(255) NOT NULL COMMENT 'BinaryAnnotation.key or Annotation.value if type == -1',
  `a_value` blob COMMENT 'BinaryAnnotation.value(), which must be smaller than 64KB',
  `a_type` int(11) NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
  `a_timestamp` bigint(20) DEFAULT NULL COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
  `endpoint_ipv4` int(11) DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_ipv6` binary(16) DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
  `endpoint_port` smallint(6) DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_service_name` varchar(255) DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
  UNIQUE KEY `trace_id_high` (`trace_id_high`,`trace_id`,`span_id`,`a_key`,`a_timestamp`) COMMENT 'Ignore insert on duplicate',
  KEY `trace_id_high_2` (`trace_id_high`,`trace_id`,`span_id`) COMMENT 'for joining with zipkin_spans',
  KEY `trace_id_high_3` (`trace_id_high`,`trace_id`) COMMENT 'for getTraces/ByIds',
  KEY `endpoint_service_name` (`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames',
  KEY `a_type` (`a_type`) COMMENT 'for getTraces',
  KEY `a_key` (`a_key`) COMMENT 'for getTraces',
  KEY `trace_id` (`trace_id`,`span_id`,`a_key`) COMMENT 'for dependencies job'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;

/*Data for the table `zipkin_annotations` */

/*Table structure for table `zipkin_dependencies` */

DROP TABLE IF EXISTS `zipkin_dependencies`;

CREATE TABLE `zipkin_dependencies` (
  `day` date NOT NULL,
  `parent` varchar(255) NOT NULL,
  `child` varchar(255) NOT NULL,
  `call_count` bigint(20) DEFAULT NULL,
  UNIQUE KEY `day` (`day`,`parent`,`child`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;

/*Data for the table `zipkin_dependencies` */

/*Table structure for table `zipkin_spans` */

DROP TABLE IF EXISTS `zipkin_spans`;

CREATE TABLE `zipkin_spans` (
  `trace_id_high` bigint(20) NOT NULL DEFAULT '0' COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` bigint(20) NOT NULL,
  `id` bigint(20) NOT NULL,
  `name` varchar(255) NOT NULL,
  `parent_id` bigint(20) DEFAULT NULL,
  `debug` bit(1) DEFAULT NULL,
  `start_ts` bigint(20) DEFAULT NULL COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
  `duration` bigint(20) DEFAULT NULL COMMENT 'Span.duration(): micros used for minDuration and maxDuration query',
  UNIQUE KEY `trace_id_high` (`trace_id_high`,`trace_id`,`id`) COMMENT 'ignore insert on duplicate',
  KEY `trace_id_high_2` (`trace_id_high`,`trace_id`,`id`) COMMENT 'for joining with zipkin_annotations',
  KEY `trace_id_high_3` (`trace_id_high`,`trace_id`) COMMENT 'for getTracesByIds',
  KEY `name` (`name`) COMMENT 'for getTraces and getSpanNames',
  KEY `start_ts` (`start_ts`) COMMENT 'for getTraces ordering and range'
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=COMPRESSED;

/*Data for the table `zipkin_spans` */

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

  • 重启Zipkin的服务端:
java -jar zipkin-server-2.12.9-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=127.0.0.1 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=root123

# STORAGE_TYPE : 存储类型
  • 此时调用微服务某个接口,可以看到trace数据已被持久化到MqSQL表中:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/765837.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ThinkPHP 多对多关联

用多对多关联的前提 如果模型 A 多对多关联模型 C&#xff0c;必须存在一张中间表 B 记录着双方的主键&#xff0c;因为就是靠着这张中间表 B 记录着模型 A 与模型 C 的关系。 举例&#xff0c;数据表结构如下 // 商品表 goodsgoods_id - integer // 商品主键goods_name - va…

【C#】并行编程实战:使用延迟初始化提高性能

在前面的章节中讨论了 C# 中线程安全并发集合&#xff0c;有助于提高代码性能、降低同步开销。本章将讨论更多有助于提高性能的概念&#xff0c;包括使用自定义实现的内置构造。 毕竟&#xff0c;对于多线程编程来讲&#xff0c;最核心的需求就是为了性能。 延迟初始化 - .NET…

手机怎么编辑pdf?这几款工具可以实现

手机怎么编辑pdf&#xff1f;在如今的数字时代&#xff0c;PDF文档已经成为了一种标准的文件格式。然而&#xff0c;当我们需要编辑这些PDF文档时&#xff0c;我们往往需要使用电脑上的专业软件&#xff0c;这给我们带来了很大的不便。不过&#xff0c;有许多手机应用程序可以让…

AIGC 大模型纷纷部署,企业如何为 AI 数据降本增效

编辑 | 宋慧 出品 | CSDN 云计算 AIGC 从年初开始持续爆火&#xff0c;国内各种大模型纷纷涌现&#xff0c;其中模型参数轻松突破千亿数量级。模型中数据的形态、部署也是多种多样的&#xff0c;庞大数据量背后的管理和成本不容小觑。 混合数据厂商肯睿 Cloudera 今年相继发布…

设计模式的概述

目录 分类 创建型模式 结构型模式 行为型模式 类之间的关系 关联关系 聚合关系 组合关系 依赖关系 继承关系 实现关系 设计原则 开闭原则 里氏代换原则 依赖倒转原则 接口隔离原则 合成复用原则 一、分类 创建型模式 用于描述“怎样创建对象”&#xff0c;它…

线程池的学习(一)

转载&#xff1a;Java 线程池 线程池的创建方式 方式一&#xff1a;创建单一线程的线程池 newSingleThreadExecutor 特点&#xff1a; 线程池中只包含 1 个线程&#xff0c;存活时间是无限的按照提交顺序执行任务唯一线程繁忙时&#xff0c;新提交的任务会被加入到阻塞队列…

Java springBoot项目报LDAP health check failed

报错内容如下&#xff1a; 在bootstrap.yml文件里加 management:health:ldap:enabled: false 配置。 或者在application.properties文件里加&#xff1a; management.health.ldap.enabledfalse 参考答案&#xff1a;LDAP health check failed 难道没有人遇到这样的问题吗&…

我造了一个新的词汇:信息湍流

信息湍流 信息湍流的简介起因有出现信息湍流的领域如何做信息湍流的计算 信息湍流的简介 在物流学中&#xff0c;一个物体从一个位置到另外一个位置&#xff0c;我们可以通过精确的公式计算来预测出新位置。 而水和气体则是大量一个一个物体组成的新物体&#xff0c;称为&…

Docker安装以及基础镜像的使用

Docker 安装 Docker 要求 CentOS 系统的内核版本高于 3.10 uname -r使用 root 权限登录 su # 输入密码更新 yum yum -y update卸载旧版本的 docker yum remove ‐y docker*安装需要的软件包 yum -y install yum-utils设置 yum 源&#xff0c;并更新 yum 包的索引 yum-config-ma…

凝心聚力,同为科技(TOWE)2023年中会议暨团建活动圆满举行

01凝心聚力 奋勇冲刺——年中会议现场 年中会议现场 时光冉冉&#xff0c;2023年已过半&#xff0c;7月4日-11日&#xff0c;为回望过往、总结成果、复盘经验&#xff0c;确保顺利完成公司年度目标&#xff0c;增强团队凝聚力、激发员工活力&#xff0c;深化企业文化建设&…

15 - 堆栈 - 大顶堆

前面我们学习了小顶堆,相信大家都已经有点概念了,今天来了解一下大顶堆。 大顶堆示意图 堆数组存放的公式 我们用简单的公式来描述一下堆的定义就是: 大顶堆:arr[i] >= arr[2i+1] && arr[i] >= arr[2i+2] 小顶堆:arr[i] <= arr[2i+1] && a…

两股热潮如何汇聚:当数字孪生遇上元宇宙

引言 随着科技的迅猛发展&#xff0c;数字孪生和元宇宙已成为当今技术界备受关注的两股热潮。这两个概念各自都在不同领域取得了突破性进展&#xff0c;但在最近的发展中&#xff0c;人们开始发现它们之间存在着潜在的契合点。本文将探讨数字孪生和元宇宙的定义、特点&#xf…

【【51单片机蜂鸣器实现起风了】】

哀伤如同风&#xff0c;消失无影踪。 前面的有两个非常关键的点希望兄弟们明白 我一开始也失算了 这里兄弟们注意务必改成int 不然会超出 就会出现播放一半从头开始的情况 下面是两份起风了代码直接附上main.c 因为另外的其实和我之前说的模板都一样复制粘贴就行 为什么是…

M1 Mac如何安装CentOS7虚拟机(图文详细解说)

1、下载相应的文件 2、打开VMware Fusion pro进行安装 3、 输入许可证密钥 4、 将CentOS-7拖入“从光盘或映像中安装”中 5、点击继续 6、选择其他-->其他64位ARM-->继续 7、进行自定设置 8、这里更改名为“Centos7”&#xff08;不要加空格&#xff09;&#xff0c;存…

2023 Testing Expo倒计时-聚焦Softing 9003展位

请点击此处&#xff0c;即可进行在线登记报名并了解更多信息&#xff01;

ES系列--文档处理

一、文档冲突 当我们使用 index API 更新文档 &#xff0c;可以一次性读取原始文档&#xff0c;做我们的修改&#xff0c;然后重 新索引 整个文档 。 最近的索引请求将获胜&#xff1a;无论最后哪一个文档被索引&#xff0c;都将被唯一存 储在 Elasticsearch 中。如果其他人同时…

Java-生成数据库设计文档

目录 场景screw 官网介绍接口编写 场景 在企业开发中&#xff0c;有些公司会要求开发人员编写数据库表结构文档&#xff0c;这项工作没啥技术含量而且很繁琐&#xff0c;每当有表发生更改时就需要维护这个文档&#xff0c;或者是需要交付数据库设计文档和导出数据库设计文档这类…

8月|龙讯旷腾高性能计算与工业材料模拟论坛2023

2023年8月25日 山东青岛 高性能计算与工业材料模拟论坛2023 青岛&#xff0c;别称岛城&#xff0c;国务院批复确定的中国沿海重要中心城市和滨海度假旅游城市&#xff0c;国家历史文化名城、中国帆船之都、世界啤酒之城、联合国电影之都&#xff0c;也是国家海洋科研和教育中…

【产品经理】TO B市场分析

市场分析是一个独立而又宏大的学科领域&#xff0c;并且具体使用中&#xff0c;目标和个体不同&#xff0c;分析的方式方法也不同。TO B产品的市场分析是对市场环境、市场规模、性质、特征、竞品进行分析&#xff0c;从而寻找和研究潜在需求的市场机会&#xff0c;帮助产品经理…

设计模式大白话——工厂模式

文章目录 设计模式大白话——工厂模式1.1、简单工厂:1.2、工厂方法1.3、抽象工厂 设计模式大白话——工厂模式 1.1、简单工厂: 场景与思路 ​ 现在需要开一个 Pizza 店&#xff0c;Pizza 店可以生产各种口味的 Pizza ​ 既然要生产各种各样的 Pizza&#xff0c;那就会很容易想…