SpringBoot集成ZipKin实现链路跟踪

2023-11-06

SpringBoot集成ZipKin实现链路跟踪

1、我们要做什么

​ 当我们的服务器成千上万,当我们的模块上万成千,当我们的调用链路复杂如蜘蛛网时,我们突然发现一个小小的性能问题却不能快速定位到点!千万不要以为自己是神,当年那个觉得ELK日志分析系统多余的程序员已经被老板祭天!

​ 废话有点多,今天我们要做的一件事非常简单,如何在一个多层调用的接口里快速查看它们的网络拓扑图并得到监控数据!

2、我们要注意什么

​ 但凡一个合格的辅助,都不能抢主力的经济,不然会影响主力DPS输出----性能轻损耗

​ 但凡一个合格的辅助,都应该跟随主力的脚步,而不能对主力指手画脚----业务非嵌入

​ 但凡一个合格的辅助,都应该尽可能的实现简单轻负载----架构轻量级

3、zipkin实现原理

​ 流程图:

在这里插入图片描述

​ 流程图包含三个重要信息:

  • Trace

    表示一条调用链路,是整个调用链路串联的唯一标识,将所有Span汇聚起来

  • Span

    通俗的理解就是一次请求信息;它是链路跟踪的基本工作单元,一次链路调用(可以是RPC,DB等没有特定的限制)创建一个span

  • Annotation

    用于定位一个request的开始和结束,cs/sr/ss/cr含有额外的信息,比如说时间点,当这个annotation被记录了,这个RPC也被认为完成了

cs:Client Start,表示客户端发起请求 ;一个span的开始;
cf:Client Finish,表示客户端获取到服务端返回信息;一个span的结束
ss:Server Start,表示服务端收到请求
sf:Server Finish,表示服务端完成处理,并将结果发送给客户端

ss-cs:网络延迟
sf-ss:逻辑处理时间
cf-cs:整个流程时间
  • Collector

    接受或者收集各个应用传输的数据,跟踪一个Http请求的工作流程:

  1. 把当前调用链的Trace信息添加到HTTP Header里面
  2. 记录当前调用的时间戳
  3. 发送HTTP请求,把trace相关的header信息携带上
  4. 调用结束之后,记录当前调用话费的时间
  5. 然后把上面流程产生的 信息汇集成一个span,把这个span信息上传到zipkin的Collector模块
  6. 下一个Http请求继续从第一步开始

4、落地实现

4.1 搭建zipkin server

持久化方式

创建zipkin持久化数据库,当然,也可以不持久化,放内存中,不过我相信您如果不想被老板祭天也不会这么干!

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for 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\r\ntrace 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) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT 'BinaryAnnotation.key or\r\nAnnotation.value if type == -1',
  `a_value` blob NULL COMMENT 'BinaryAnnotation.value(), which must be smaller than\r\n64KB',
  `a_type` int(11) NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
  `a_timestamp` bigint(20) NULL DEFAULT NULL COMMENT 'Used to implement TTL; Annotation.timestamp or\r\nzipkin_spans.timestamp',
  `endpoint_ipv4` int(11) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_ipv6` binary(16) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is\r\nnull, or no IPv6 address',
  `endpoint_port` smallint(6) NULL DEFAULT NULL COMMENT 'Null when Binary/Annotation.endpoint is\r\nnull',
  `endpoint_service_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT 'Null when\r\nBinary/Annotation.endpoint is null',
  UNIQUE INDEX `trace_id_high`(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) USING BTREE COMMENT 'Ignore insert on duplicate',
  INDEX `trace_id_high_2`(`trace_id_high`, `trace_id`, `span_id`) USING BTREE COMMENT 'for joining with zipkin_spans',
  INDEX `trace_id_high_3`(`trace_id_high`, `trace_id`) USING BTREE COMMENT 'for getTraces/ByIds',
  INDEX `endpoint_service_name`(`endpoint_service_name`) USING BTREE COMMENT 'for\r\ngetTraces and getServiceNames',
  INDEX `a_type`(`a_type`) USING BTREE COMMENT 'for getTraces and\r\nautocomplete values',
  INDEX `a_key`(`a_key`) USING BTREE COMMENT 'for getTraces and\r\nautocomplete values',
  INDEX `trace_id`(`trace_id`, `span_id`, `a_key`) USING BTREE COMMENT 'for dependencies job'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPRESSED;

-- ----------------------------
-- Table structure for 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\r\ntrace uses 128 bit traceIds instead of 64 bit',
  `trace_id` bigint(20) NOT NULL,
  `id` bigint(20) NOT NULL,
  `name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
  `remote_service_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `parent_id` bigint(20) NULL DEFAULT NULL,
  `debug` bit(1) NULL DEFAULT NULL,
  `start_ts` bigint(20) NULL DEFAULT NULL COMMENT 'Span.timestamp(): epoch micros used for endTs query\r\nand to implement TTL',
  `duration` bigint(20) NULL DEFAULT NULL COMMENT 'Span.duration(): micros used for minDuration and\r\nmaxDuration query',
  PRIMARY KEY (`trace_id_high`, `trace_id`, `id`) USING BTREE,
  INDEX `trace_id_high`(`trace_id_high`, `trace_id`) USING BTREE COMMENT 'for\r\ngetTracesByIds',
  INDEX `name`(`name`) USING BTREE COMMENT 'for getTraces and\r\ngetSpanNames',
  INDEX `remote_service_name`(`remote_service_name`) USING BTREE COMMENT 'for getTraces\r\nand getRemoteServiceNames',
  INDEX `start_ts`(`start_ts`) USING BTREE COMMENT 'for getTraces ordering\r\nand range'
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = COMPRESSED;

-- ----------------------------
-- Records of zipkin_annotations
-- ----------------------------
set global innodb_large_prefix=1;
set global innodb_file_format=BARRACUDA;
-- ----------------------------
-- Table structure for zipkin_dependencies
-- ----------------------------
DROP TABLE IF EXISTS `zipkin_dependencies`;
CREATE TABLE `zipkin_dependencies`  (
  `day` date NOT NULL,
  `parent` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `child` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `call_count` bigint(20) NULL DEFAULT NULL,
  `error_count` bigint(20) NULL DEFAULT NULL,
  PRIMARY KEY (`day`, `parent`, `child`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = COMPRESSED;

SET FOREIGN_KEY_CHECKS = 1;

部署zipkin server

使用Docker Compose部署zipkin server

 zipkin:
    image: openzipkin/zipkin
    container_name: zipkin
    environment:
      - STORAGE_TYPE=mysql
      # Point the zipkin at the storage backend
      - MYSQL_DB=zipkin
      - MYSQL_USER=root
      - MYSQL_PASS=root
      - MYSQL_HOST=192.168.137.129
      - MYSQL_TCP_PORT=3306
    network_mode: host
    ports:
      # Port used for the Zipkin UI and HTTP Api
      - 9411:9411

配置好数据库,启动docker容器

在这里插入图片描述
通过web浏览器访问如下,表示搭建成功
在这里插入图片描述

4.2 客户端嵌入zipkin跟踪

测试链路

非常简单,四个应用服务,调用深度为三层!

在这里插入图片描述

引入依赖

每个zipkin客户端服务都引入如下依赖:

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
        <dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-sleuth-zipkin</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.cloud</groupId>
			<artifactId>spring-cloud-starter-sleuth</artifactId>
		</dependency>
	</dependencies>
服务调用代码
  • service1

    package com.paratera.console.linktracking.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    @RequestMapping("/service1")
    public class ZipkinBraveController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @RequestMapping("/test")
        public String service1() throws Exception {
            //休眠100ms,模拟业务处理耗时
            Thread.sleep(100);
            //调用service2服务
            ResponseEntity<String> res = restTemplate.getForEntity("http://localhost:8082/service2/test", String.class);
            return res.getBody();
        }
    }
    
  • service2

    package com.paratera.console.linktracking.controller;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.http.ResponseEntity;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    import org.springframework.web.client.RestTemplate;
    
    @RestController
    @RequestMapping("/service2")
    public class ZipkinBraveController {
    
        @Autowired
        private RestTemplate restTemplate;
    
        @RequestMapping("/test")
        public String service1() throws Exception {
            //休眠200ms,模拟业务处理
            Thread.sleep(200);
            //调用service3服务
            ResponseEntity<String> res1 = restTemplate.getForEntity("http://localhost:8083/service3/test", String.class);
            //调用service4服务
            ResponseEntity<String> res2 = restTemplate.getForEntity("http://localhost:8084/service4/test", String.class);
            return res1.getBody()+":"+res2.getBody();
        }
    }
    
  • service3

    package com.paratera.console.linktracking.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/service3")
    public class ZipkinBraveController {
    
        @RequestMapping("/test")
        public String service1() throws Exception {
            //休眠3s,模拟性能耗点
            Thread.sleep(3000);
            return "service3";
        }
    }
    
  • service4

    package com.paratera.console.linktracking.controller;
    
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    @RestController
    @RequestMapping("/service4")
    public class ZipkinBraveController {
    
        @RequestMapping("/test")
        public String service1() throws Exception {
            //休眠100ms,模拟业务耗时
            Thread.sleep(100);
            return "service4";
        }
    
    }
    
application.yml配置
spring:
  application:
    name: service1
  zipkin:
    base-url: http://192.168.137.129:9411    #zipkin server 的地址
    sender:
      type: web    #如果ClassPath里没有kafka, active MQ, 默认是web的方式
    sleuth:
      sampler:
        probability: 1.0  #100%取样,生产环境应该低一点,用不着全部取出来
server:
  port: 8081

四个服务工程除了端口不一样,其他都一样,zipkin监控serviceName不做配置,默认会使用Spring Application Name

附RestTemplate实例化代码
@Bean
public RestTemplate restTemplate(ClientHttpRequestFactory factory) {
   return new RestTemplate(factory);
}

@Bean
public ClientHttpRequestFactory clientHttpRequestFactory() {
   SimpleClientHttpRequestFactory factory = new SimpleClientHttpRequestFactory();
   factory.setConnectTimeout(5000);
   factory.setReadTimeout(5000);
   return factory;
}

4.3 测试结果

当我们访问http://localhost:8081/service1/test时,会生成一个完整的调用链路json数据,通过4.1搭建的zipkin server UI可以查看详情:

在这里插入图片描述

点击show查看各server请求详情:

在这里插入图片描述

进入service3详情:

在这里插入图片描述

可以自己通过CS,SS,CF,SF计算是网络延迟引起的问题还是逻辑处理引起的性能问题!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

SpringBoot集成ZipKin实现链路跟踪 的相关文章

  • 在java中轮询Http服务器(重复发送http get请求)

    当对其进行 REST 调用时 我的 Web 服务器会发送一些信息 我想不断轮询该服务器 间隔5秒后重复发送HTTP GET请求 以检查返回的信息是否有任何变化 做到这一点最有效的方法是什么 您能提供一些代码示例吗 请注意 我只想开发客户端代
  • 按下按钮并在java中的新窗口中打开文件

    我创建了一个 JFrame 并放置了一个文本字段和按钮 在文本字段中我放置了从文本文件读取的名称 我知道我想单击按钮并打开一个已知窗口 我想在其中放置名称 其他信息来自同一个文件 这是我的代码 这是我的主框架 package Fronten
  • 带路径压缩算法的加权 Quick-Union

    有一种 带路径压缩的加权快速联合 算法 代码 public class WeightedQU private int id private int iz public WeightedQU int N id new int N iz new
  • 如何在由子控件组成的 SWT 复合材料上跟踪鼠标?

    我创建了自己的控件 我想跟踪鼠标并添加一个MouseTrackListener 很遗憾MouseEnter and MouseLeave当鼠标移动到我的合成部分 即标签和按钮 上时 也会生成事件 Mouse enter mouse ente
  • 有没有创建 Cron 表达式的 Java 代码? [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 我需要一个 Java 代码来根据用户输入创建一个 cron 表达式 用户输入是时间 频率和执行次数 只需从评论中添加 自己创建 即可
  • TreeMap 删除所有大于某个键的键

    在项目中 我需要删除键值大于某个键的所有对象 键类型为Date 如果重要的话 据我所知TreeMapJava中实现的是红黑树 它是一种二叉搜索树 所以我应该得到O n 删除子树时 但除了制作尾部视图并一一删除之外 我找不到任何方法可以做到这
  • java.lang.ClassNotFoundException:javax.mail.MessagingException

    我想使用 eclipse 将电子邮件从我的 gmail 帐户发送到另一个邮件帐户 我使用 apache tomcat 7 0 34 作为我的 Web 服务器 并使用端口 8080 作为 apache 服务器 HTTP 1 1 并使用 JRE
  • 两个整数乘积的模

    我必须找到c c a b mod m a b c m 是 32 位整数 但 a b 可以超过 32 位 我正在尝试找出一种计算 c 的方法 而不使用 long 或任何 gt 32 位的数据类型 有任何想法吗 如果m是质数 事情可以简化吗 注
  • 垃圾收集器如何在幕后工作来收集死对象?

    我正在阅读有关垃圾收集的内容 众所周知 垃圾收集会收集死亡对象并回收内存 我的问题是 Collector 如何知道任何对象已死亡 它使用什么数据结构来跟踪活动对象 我正在研究这个问题 我发现GC实际上会跟踪活动对象 并标记它们 每个未标记的
  • 将巨大的模式编译成Java

    有两个主要工具提供了将 XSD 模式编译为 Java 的方法 xmlbeans 和 JAXB 问题是 XSD 模式确实很大 30MB 的 XML 文件 大部分模式在我的项目中没有使用 所以我可以注释掉大部分代码 但这不是一个好的解决方案 目
  • Runtime.exec 处理包含多个空格的参数

    我怎样才能进行以下运行 public class ExecTest public static void main String args try Notice the multiple spaces in the argument Str
  • 断言 Kafka 发送有效

    我正在使用 Spring Boot 编写一个应用程序 因此要写信给 Kafka 我这样做 Autowired private KafkaTemplate
  • 如何在字段值无效的情况下更改 Struts2 验证错误消息?

    我在 Web 表单上使用 Struts2 验证 如果字段假设为整数或日期 则
  • Jetty、websocket、java.lang.RuntimeException:无法加载平台配置器

    我尝试在 Endpoint 中获取 http 会话 我遵循了这个建议https stackoverflow com a 17994303 https stackoverflow com a 17994303 这就是我这样做的原因 publi
  • 如何在JPanel中设置背景图片

    你好 我使用 JPanel 作为我的框架的容器 然后我真的想在我的面板中使用背景图片 我真的需要帮助 这是我到目前为止的代码 这是更新 请检查这里是我的代码 import java awt import javax swing import
  • JDBC 时间戳和日期 GMT 问题

    我有一个 JDBC 日期列 如果我使用 getDate 则会得到 date 仅部分2009 年 10 月 2 日但如果我使用 getTimestamp 我会得到完整的 date 2009 年 10 月 2 日 13 56 78 890 这正
  • Java Swing - 如何禁用 JPanel?

    我有一些JComponents on a JPanel我想在按下 开始 按钮时禁用所有这些组件 目前 我通过以下方式显式禁用所有组件 component1 setEnabled false 但是有什么办法可以一次性禁用所有组件吗 我尝试禁用
  • 将 JavaFX FXML 对象分组在一起

    非常具有描述性和信息性的答案将从我这里获得价值 50 声望的赏金 我正在 JavaFX 中开发一个应用程序 对于视图 我使用 FXML
  • java XMLSerializer 避免复杂的空元素

    我有这个代码 DocumentBuilderFactory factory DocumentBuilderFactory newInstance DocumentBuilder builder factory newDocumentBuil
  • 由 Servlet 容器提供服务的 WebSocket

    上周我研究了 WebSockets 并对如何使用 Java Servlet API 实现服务器端进行了一些思考 我没有花费太多时间 但在使用 Tomcat 进行一些测试时遇到了以下问题 如果不修补容器或至少对 HttpServletResp

随机推荐

  • Arthas 常用命令

    官方文档 Arthas Install Arthas 3 5 5 文档 安装 Arthas 是阿里开源的一款 linux mac 上性能问题排查工具 文档链接 Arthas 用户文档 Arthas 3 5 5 文档 这个里边具体步骤和指令讲
  • 数据链路层:ARP协议详解(绝对经典)

    ARP协议定义 地址解析协议 工作在数据链路层 在本层和硬件接口联系 同时向上层提供服务 IP数据包常通过以太网发送 以太网设备不识别32位IP地址 他们是以48位以太网地址传输以太网数据包的 因此需要IP转化为以太网目的地址 ARP协议用
  • Thread Pool 线程池

    Thread Pool 本文基于经典的99行代码 稍加修改使其支持C 20 并增加了wait与join功能 pragma once include
  • vue中使用drag事件左右拖动div,改变宽高大小

    实现思路 1 使用上左 top left 上 top 上右 top right 等6个小点实现拖动效果 2 拖动时记录起始点 结束点 startPoint x 0 y 0 开始坐标 拖动改变定位 endPoint x 0 y 0 结束坐标
  • 面试题 08.10. 颜色填充

    面试题 08 10 颜色填充 https leetcode cn com problems color fill lcci 难度简单12收藏分享切换为英文关注反馈 编写函数 实现许多图片编辑软件都支持的 颜色填充 功能 待填充的图像用二维数
  • Java多线程之间的通信

    重点 等待 gt 执行业务 gt 通知其他线程 package com liu pc 线程之间通讯问题 等待唤醒 通知唤醒 线程交替执行 A B操作同一个变量 A 1 B 1 public class A public static voi
  • virtual channels 虚拟通道——mipi协议

    1 虚拟通道ID字段 最多可以支持4个外设 2 需要 DSI Hub 无法将多个显示器连接到同一总线 3 或者某个显示设备支持使用虚拟通道 设备本身由多个物理驱动器控制显示面板的不同区域 这个显示器就可以使用虚拟通道将数据发送到各个驱动器
  • 【数据库原理及应用教程(第4版

    文章目录 一 选择题 二 填空题 三 设计题 四 简答题 Reference 一 选择题 1 2 3 4 5 6 7 8 9 10 B C C A C B C B D C 11 12 13 14 15 16 17 18 19 20 D B
  • bzoj1110 [POI2007]砝码Odw 贪心+进制拆分

    题意就不说了 一开始居然在想直接dp 看到是整数倍我的内心居然毫无波动 真是傻的不行了 因为是整数倍 那我们可以把一个容器用砝码的重量做为进制拆分 然后从小到大一个个填就可以了 贪心策略肯定是最优的 具体如何拆分看hzwer www htt
  • LSP和Hooks拦截

    分层服务提供者 英语 Layered Service Provider 缩写LSP 是一项已被弃用的Microsoft Windows中Winsock 2服务提供者接口 SPI 的特性 它也被称为分层服务提供商或分层服务提供程序 分层服务提
  • Mybatis-plus中操作JSON字段

    1 实体类上要加上自动映射 TableName value school autoResultMap true 2 json字段上加上json处理器 TableField value cover url typeHandler Jackso
  • 使用nmcli命令配置虚拟机网络

    简述 什么是nmcli Description nmcli is a command line tool for controlling NetworkManager and reporting network status It can
  • Mybatis 获取当前序列和下一个序列值 以及在一个方法中写多条SQL 语句

    目录 1 Mybatis 获取当前序列和下一个序列值 2 Mybatis 在一个方法中写多条SQL 语句 1 Mybatis 获取当前序列和下一个序列值 获取当前序列值 select XXX sequence currval from du
  • 电子信息工程毕设题目选题大全

    文章目录 1前言 2 如何选题 3 选题方向 3 1 嵌入式开发方向 3 2 物联网方向 3 3 移动通信方向 3 4 人工智能方向 3 5 算法研究方向 3 6 移动应用开发方向 3 7 网络通信方向 3 8 学长作品展示 4 最后 1前
  • Jetpack-Compose之一基础使用

    一 命令式UI和申明式UI 如果之前有了解或者使用果Flutter 应该会对命令式UI这种架构不陌生 目前申明式UI确实是很火包含Flutter SwiftUI JetpackCompose都使用了该种方式 2021年7月底 Google
  • mysql数据库容量规划_MySQL数据库服务器整体规划(方法论)

    我们在搭建MySQL数据库服务器的开始阶段就合理的规划 可以避免以后的很多问题的产生 大大节省我们的时间和精力 在一定幅度上降低成本 当然 这会涉及很多方面 比如机器的选型 业务评估和系统规划等 所有的设计都是跟具体的需求相关的 我们首先要
  • 什么是 DNS ANAME 解析?

    本人使用谷歌搜索了简中互联网 完全没有找到任何有关 ANAME 的文章 本文该不会是头一份吧 相信大家对于 DNS 的解析方式都不陌生 常见的有 A CNAME MX TXT 记录等等 其中 网站常用的是 A 记录和 CNAME 记录 A
  • [贪心入门]完美字符串

    约翰认为字符串的完美度等于它里面所有字母的完美度之和 每个字母的完美度可以由你来分配 不同字母的完美度不同 分别对应一个1 26之间的整数 约翰不在乎字母大小写 也就是说字母F和f 的完美度相同 给定一个字符串 输出它的最大可能的完美度 例
  • spyglass的waiver使用问题总结-工具(八)

    spyglass使用过程中waiver warning及error过程中总会出现生效不成功的问题 总结使用步骤供参考 实践出真知 解决问题就是好方法 1 在spyglass的prj中设置默认waiver文件 2 如何waiver 3 查看已
  • SpringBoot集成ZipKin实现链路跟踪

    SpringBoot集成ZipKin实现链路跟踪 1 我们要做什么 当我们的服务器成千上万 当我们的模块上万成千 当我们的调用链路复杂如蜘蛛网时 我们突然发现一个小小的性能问题却不能快速定位到点 千万不要以为自己是神 当年那个觉得ELK日志