快速入门链路追踪sleuth整合zipkin(代码演示)

news2024/10/5 19:06:24

1、演示项目背景

2、pom.xml

3、启动项目

4、测试

5、保存数据到数据库

6、通过mq保存数据到mysql

7、通过mq保存数据到es


1、演示项目背景

下载zipkin,建议使用2.x版本的,3.x版本的要求jdk高版本。如果自己是1.8,就下载2.x

下载地址:Central Repository: io/zipkin/zipkin-server (maven.org)

使用consul作为注册配置中心,自己也可以使用nacos等其他的。

三个微服务(consumer和provider代码在上一篇文章)

新加个gateway是为了更能清楚查看链路信息

service-gateway代码

application.yml

server:
  port: 9092
spring:
  application:
    name: service-gateway
  cloud:
    consul:
      host: localhost
      port: 8500
      discovery:
        register: true  #是否需要注册
        instance-id: ${spring.application.name}-01 #实例名称(必须唯一)
        service-name: ${spring.application.name} #服务名称
        port: ${server.port}  #服务端口
        prefer-ip-address: true #是否使用ip注册服务
        ip-address: ${spring.cloud.client.ip-address} #请求服务ip地址
        health-check-timeout: 5s
    gateway:
      routes:
        - id: service-consumer
          uri: lb://service-consumer
          predicates:
            - Path=/service-consumer/**
          filters:
            - StripPrefix=1

        - id: service-provider
          uri: lb://service-provider
          predicates:
            - Path=/service-provider/**
          filters:
            - StripPrefix=1
  zipkin:
    base-url: http://localhost:9411/ 
    sender:
      type: web     #传输方式,web、rabbit、kafka、rocketmq
  sleuth:
    sampler:
      probability: 1.0   #应该采样的请求的概率。 
#例如。 1.0-应抽样100%的请求。 精度仅是整数(即不支持0.1%的迹线).    如果是1.0就会保存所有的请求。

启动类

package com.txd;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

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

pom

 <dependencies>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-discovery</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

service-consumer的yml

server:
  port: 9090
spring:
  application:
    name: service-consumer
  cloud:
    consul:
      host: localhost
      port: 8500

      discovery:
        register: true  #是否需要注册
        instance-id: ${spring.application.name}-01 #实例名称(必须唯一)
        service-name: ${spring.application.name} #服务名称
        port: ${server.port}  #服务端口
        prefer-ip-address: true #是否使用ip注册服务
        ip-address: ${spring.cloud.client.ip-address} #请求服务ip地址

  zipkin:
    base-url: http://localhost:9411/ 
    sender:
      type: web     #传输方式,web、rabbit、kafka、rocketmq
  sleuth:
    sampler:
      probability: 1.0    #应该采样的请求的概率。 
#例如。 1.0-应抽样100%的请求。 精度仅是整数(即不支持0.1%的迹线).    如果是1.0就会保存所有的请求。

service-provider的yml


spring:
  application:
    name: service-provider
  cloud:
    consul:
      host: localhost
      port: 8500

      discovery:
        register: true  #是否需要注册
        instance-id: ${spring.application.name}-01 #实例名称(必须唯一)
        service-name: ${spring.application.name} #服务名称
        port: ${server.port}  #服务端口
        prefer-ip-address: true #是否使用ip注册服务
        ip-address: ${spring.cloud.client.ip-address} #请求服务ip地址
      config:
        enabled: true     #是否开启配置中心
        format: yaml      #配置文件格式,这里用的yaml
        profile-separator: "-"  #例如: service-provider和dev中间的符号 用-就是service-provider-dev
        data-key: data    #默认的值就是data  是config的key
        prefix: config    #默认的值就是config 是配置的前缀
  profiles:
    active: dev
  zipkin:
    base-url: http://localhost:9411/  
    sender:
      type: web     #传输方式,web、rabbit、kafka、rocketmq
  sleuth:
    sampler:
      probability: 1.0    #应该采样的请求的概率。 
#例如。 1.0-应抽样100%的请求。 精度仅是整数(即不支持0.1%的迹线).    如果是1.0就会保存所有的请求。

server:
  port: 9091

2、pom.xml

因为需要用sleuth和zipkin,依赖必须导。保证三个微服务都有

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
            <version>2.2.1.RELEASE</version>
        </dependency>

3、启动项目

保证consul和zipkin服务端都已经运行

zipkin启动:        java -jar zipkin....jar

consul启动:    consul.exe agent -dev

启动后分别访问:localhost:8500        localhost:9411 

启动三个微服务项目,查看consul都已经注册上去了

4、测试

接口逻辑1:通过gateway网关访问consumer服务,consumer服务调用provider服务

接口逻辑2:直接访问consumer服务,consumer服务调用provider服务

测试接口:访问localhost:9092/service-consumer/1

查看zipkin:

可以看到我们调用的方法,经过了三个服务的链路(其他的链路是consul的异步请求不用管)

点进去查看,我们可以看到每一个服务的耗时、地址等信息。

点击依赖:

我们可以看到每个服务之间的调用关系

直接访问consumer服务,不经过网关:localhost:9090/1

如果太多了,我们可以进行筛选:

现在的请求都是保存在内存中,如果我们重启zipkin这些链路数据就会全部丢失。

5、保存数据到数据库

不用改代码

新建数据库zipkin        建表语句(官方提供的,我复制到这里)

CREATE TABLE IF NOT EXISTS zipkin_spans (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL,
  `id` BIGINT NOT NULL,
  `name` VARCHAR(255) NOT NULL,
  `remote_service_name` VARCHAR(255),
  `parent_id` BIGINT,
  `debug` BIT(1),
  `start_ts` BIGINT COMMENT 'Span.timestamp(): epoch micros used for endTs query and to implement TTL',
  `duration` BIGINT COMMENT 'Span.duration(): micros used for minDuration and maxDuration query',
  PRIMARY KEY (`trace_id_high`, `trace_id`, `id`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_spans ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTracesByIds';
ALTER TABLE zipkin_spans ADD INDEX(`name`) COMMENT 'for getTraces and getSpanNames';
ALTER TABLE zipkin_spans ADD INDEX(`remote_service_name`) COMMENT 'for getTraces and getRemoteServiceNames';
ALTER TABLE zipkin_spans ADD INDEX(`start_ts`) COMMENT 'for getTraces ordering and range';

CREATE TABLE IF NOT EXISTS zipkin_annotations (
  `trace_id_high` BIGINT NOT NULL DEFAULT 0 COMMENT 'If non zero, this means the trace uses 128 bit traceIds instead of 64 bit',
  `trace_id` BIGINT NOT NULL COMMENT 'coincides with zipkin_spans.trace_id',
  `span_id` BIGINT 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 NOT NULL COMMENT 'BinaryAnnotation.type() or -1 if Annotation',
  `a_timestamp` BIGINT COMMENT 'Used to implement TTL; Annotation.timestamp or zipkin_spans.timestamp',
  `endpoint_ipv4` INT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_ipv6` BINARY(16) COMMENT 'Null when Binary/Annotation.endpoint is null, or no IPv6 address',
  `endpoint_port` SMALLINT COMMENT 'Null when Binary/Annotation.endpoint is null',
  `endpoint_service_name` VARCHAR(255) COMMENT 'Null when Binary/Annotation.endpoint is null'
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

ALTER TABLE zipkin_annotations ADD UNIQUE KEY(`trace_id_high`, `trace_id`, `span_id`, `a_key`, `a_timestamp`) COMMENT 'Ignore insert on duplicate';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`, `span_id`) COMMENT 'for joining with zipkin_spans';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id_high`, `trace_id`) COMMENT 'for getTraces/ByIds';
ALTER TABLE zipkin_annotations ADD INDEX(`endpoint_service_name`) COMMENT 'for getTraces and getServiceNames';
ALTER TABLE zipkin_annotations ADD INDEX(`a_type`) COMMENT 'for getTraces and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`a_key`) COMMENT 'for getTraces and autocomplete values';
ALTER TABLE zipkin_annotations ADD INDEX(`trace_id`, `span_id`, `a_key`) COMMENT 'for dependencies job';

CREATE TABLE IF NOT EXISTS zipkin_dependencies (
  `day` DATE NOT NULL,
  `parent` VARCHAR(255) NOT NULL,
  `child` VARCHAR(255) NOT NULL,
  `call_count` BIGINT,
  `error_count` BIGINT,
  PRIMARY KEY (`day`, `parent`, `child`)
) ENGINE=InnoDB ROW_FORMAT=COMPRESSED CHARACTER SET=utf8 COLLATE utf8_general_ci;

重新启动zipkin,启动命令:

java -jar zipkin-server-2.24.1-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=localhost --MYSQL_TCP_PORT=3306 --MYSQL_USER=root --MYSQL_PASS=123456 --MYSQL_DB=zipkin

可以发现数据已经存入到mysql中,当我们继续使用上面配置数据库命令启动时就会自动恢复数据库中的数据

链路信息是巨多的,长时间持续写入对数据库压力也是巨大的

6、通过mq保存数据到mysql

给三个微服务都添加rabbit依赖

        <dependency>
            <groupId>org.springframework.amqp</groupId>
            <artifactId>spring-rabbit</artifactId>
        </dependency>

修改配置文件:(三个都修改)


spring:
  application:
    name: service-provider
  cloud:
    consul:
      host: localhost
      port: 8500

      discovery:
        register: true  #是否需要注册
        instance-id: ${spring.application.name}-01 #实例名称(必须唯一)
        service-name: ${spring.application.name} #服务名称
        port: ${server.port}  #服务端口
        prefer-ip-address: true #是否使用ip注册服务
        ip-address: ${spring.cloud.client.ip-address} #请求服务ip地址
      config:
        enabled: true     #是否开启配置中心
        format: yaml      #配置文件格式,这里用的yaml
        profile-separator: "-"  #例如: service-provider和dev中间的符号 用-就是service-provider-dev
        data-key: data    #默认的值就是data  是config的key
        prefix: config    #默认的值就是config 是配置的前缀

  profiles:
    active: dev

  zipkin:
    base-url: http://localhost:9411/  #服务名称
    sender:
      #传输方式改为rabbit
      type: rabbit     #传输方式,web、rabbit、kafka、rocketmq
    #指定rabbitmq的传输队列
    rabbitmq:
      queue: zipkin
  sleuth:
    sampler:
      probability: 1.0

#rabbitmq相关配置
  rabbitmq:
    addresses: 192.168.133.102
    port: 5672
    username: guest
    password: guest
    listener:
      direct:
        retry:
          enabled: true
          max-attempts: 5
          initial-interval: 5000
      simple:
        retry:
          enabled: true
          max-attempts: 5
          initial-interval: 5000
server:
  port: 9091


启动rabbitmq。

为了更加清楚看到链路数据发送到mq中,我们先关掉zipkin服务端。

如果打开,消息发送到mq就会被直接消费掉。

并且清空数据库之前的链路数据,清空三个表的数据。

现在队列是没有任何东西的,我们重新启动三个服务

数据库zipkin表中也没有任何数据

启动微服务项目

可以看到zipkin队列已经自动创建出来了,而且也有了消息。(注册中心调用的异步请求)

我们再调用几次接口

启动zipkin(连接信息换成自己的)

java -jar zipkin-server-2.24.1-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=localhost --MYSQL_TCP_PORT=3306--MYSQL_USER=root --MYSQL_PASS=123456 --MYSQL_DB=zipkin --RABBIT_ADDRESSES=192.168.133.102:5672 --RABBIT_USER=guest --RABBIT_P
ASSWORD=guest --RABBIT_VIRTUAL_HOST=/ --RABBIT_QUEUE=zipkin

配置数据库信息和RabbitMQ连接信息

可以看到zipkin中已经有了链路数据

再查看数据库

数据也已经成功保存到mysql中

7、通过mq保存数据到es

不用修改代码,启动es服务   ,启动kibana

重新启动zipkin

启动命令:(换成自己的es地址和mq地址)

java -jar zipkin-server-2.24.1-exec.jar --STORAGE_TYPE=elasticsearch --ES_HOSTS=192.168.133.102:9200 --RABBIT_ADDRESSES=192.168.133.102:5672 --RABBIT_USER=guest --RABBIT_PASSWORD=guest --RABBIT_QUEUE=zipkin

启动微服务项目

查看rabbitmq界面(已经有数据被消费了)

这时候查看elasticsearch

打开192.168.133.102:5601

zipkin会自动根据当前年月日创建index

可以看到数据已经成功被存储到es中了

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

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

相关文章

Win11 ubuntu子系统安装WslRegisterDistribution failed with error: 0x800701bc

执行完这两部&#xff0c;然后再打开ubuntu即可。链接

GitHub生成SSH密钥,使用SSH进行连接

目录 一、生成新的SSH密钥 二、添加新的SSH密钥 三、测试SSH连接 四、SSH密钥密码 五、创建新仓库并推送到github 说明 使用 SSH URL 将 git clone、git fetch、git pull 或 git push 执行到远程存储库时&#xff0c; 须在计算机上生成 SSH 密钥对&#xff0c;并将公钥添加到…

YOLOv10:实时端到端目标检测的新突破

目标检测作为计算机视觉领域的一个核心问题&#xff0c;其关键在于能够在图像中准确识别并定位对象。随着深度学习技术的发展&#xff0c;基于深度神经网络的目标检测方法不断涌现&#xff0c;其中YOLO&#xff08;You Only Look Once&#xff09;系列算法以其优异的实时性和准…

共筑安全防线 展望数字未来︱智汇云舟亮相广西网络安全与信息化高峰论坛

“没有网络安全&#xff0c;就没有国家安全”。自网络安全法颁布以来&#xff0c;国家及地方各级政府、企事业单位和社会各界高度重视并积极参与其中&#xff0c;信息系统的建设离不开网络安全体系的保障支撑&#xff0c;尤其在以数字孪生技术实现的综合业务管理平台设计中&…

GAT1399协议分析(10)--视频定义及解析

一、官方定义 二、字段解析 VideoID 类型BasicObjectID 解析参考GAT1399协议分析(8)--ImageInfo字段详解-CSDN博客 InfoKind 采集类型

工具:Linux如何挂载NTFS移动硬盘

从windows平台迁移数据至Linux平台&#xff0c;有时候会用到NTFS文件系统的硬盘&#xff0c;但Linux的file system一般又无法直接兼容NTFS系统。这个就需要用到ntfs-3g插件。 NTFS-3G是一个开源项目&#xff0c; NTFS-3G是为Linux, Android, Mac OS X, FreeBSD, NetBSD, OpenSo…

据阿谱尔调研显示,中国浮法玻璃产量大约占全球总产量的1/3以上

浮法玻璃是一种通过浸入熔融金属表面形成的玻璃板&#xff0c;其制造过程被称为浮法工艺。这一工艺的核心在于将熔化后的玻璃液顺利浮在低熔点的金属&#xff08;通常是锡&#xff09;表面上&#xff0c;使得玻璃板具有均匀的厚度和平整的表面。其化学成分主要由二氧化硅、氧化…

信创国产化 | 聚铭网络携手银河麒麟完成产品兼容性互认证

在我国信创国产化战略深入推进的大背景下&#xff0c;聚铭网络与麒麟软件积极响应国家号召&#xff0c;共同致力于软件和操作系统的国产化发展。近日&#xff0c;双方宣布已完成产品兼容性互认证工作&#xff0c;这一成果标志着两家公司在信创国产化道路上迈出了坚实的一步。 …

智能引领医疗新纪元:RFID技术在医疗器械管理中的高端应用

智能引领医疗新纪元&#xff1a;RFID技术在医疗器械管理中的高端应用 随着医疗技术的快速发展&#xff0c;医疗器械在医疗行业中扮演着至关重要的角色。然而&#xff0c;如何有效地管理这些医疗器械&#xff0c;确保其安全、准确、及时地服务于患者&#xff0c;一直是医疗机构…

DSP问题:TMS320F280049延时和实际不符

1、问题现象 我之前写的一篇点灯文章&#xff0c;发现LED等闪烁频率和设想不一致&#xff0c;延时100ms&#xff0c;实际延时要更长。 2、问题原因 电路中使用的晶振是10MHz&#xff0c;实际代码中配置的是20MHz的晶振。 3、解决方案 修改代码中的晶振配置为10MHz即可。…

俯视角2D游戏_02 子弹对象池

[!NOTE] 对象池 应用场合:这种做法常用于子弹这种会大量产生的对象 &#xff0c;目的是减少性能的损耗 基本思路:产生的对象是有限的&#xff0c;并且加入到"对象池"的数组中不进行销毁&#xff0c;当需要使用时&#xff0c;再从对象池中提取对象循环利用&#xff0c…

1961. 检查字符串是否为数组前缀 - 力扣

1. 题目 给你一个字符串 s 和一个字符串数组 words &#xff0c;请你判断 s 是否为 words 的 前缀字符串 。 字符串 s 要成为 words 的 前缀字符串 &#xff0c;需要满足&#xff1a;s 可以由 words 中的前 k&#xff08;k 为 正数 &#xff09;个字符串按顺序相连得到&#xf…

Lab_ Exploiting a mass assignment vulnerability_实验室:利用大规模分配漏洞

使用 wiener:peter 登录 点击轻量级“l33t”皮夹克产品并将其添加到购物篮中。 去到购物车&#xff0c;点击下单&#xff0c;提示Not enough store credit for this purchase&#xff08;没有足够的商店信用用于此次购买&#xff09; 在Burp的HTTP历史记录中发现了API的请求…

Vivado 比特流编译时间获取以及FPGA电压温度获取(实用)

Vivado 比特流编译时间获取以及FPGA电压温度获取 语言 &#xff1a;Verilg HDL 、VHDL EDA工具&#xff1a;ISE、Vivado Vivado 比特流编译时间获取以及FPGA电压温度获取一、引言二、 获取FPGA 当前程序的编译时间verilog中直接调用下面源语2. FPGA电压温度获取&#xff08;1&a…

解决CentOS 7无法识别ntfs的问题

解决CentOS 7无法识别ntfs的问题 方式一&#xff1a; Centos默认不支持ntfs文件格式&#xff0c;直接在Centos7上插U盘或移动硬盘无法识别&#xff0c;安装 ntfs-3g即可&#xff1a; # yum install epel-release -y # yum install ntfs-3g -y[rootbogon ~]# rpm -qa | grep nt…

外贸干货|如何提高商机转化率?

常常听到外贸业务员抱怨“询盘质量不高”、“有询盘没转化”、“有些客户只是来比价格的”……想必大家都不陌生&#xff01; 但难道只有询盘问题、客户问题吗&#xff1f;我们自身的处理真的没问题吗&#xff1f;我想只有更多的自省自查我们可以控制的问题&#xff0c;优化我们…

尚云SunClouds打造以云算力为核心的混合云平台!

在数字经济迅猛发展的今天&#xff0c;算力已跃升为新基础能源&#xff0c;人工智能成为引领产业革新的核心工具。5月24日&#xff0c;尚云依托尚航科技全国智算中心的资源网络&#xff0c;打造了以云算力为核心的新一代混合云平台&#xff0c;尚云SunClouds品牌焕新上线&#…

React -- memo允许你的组件在 props 没有改变的情况下跳过重新渲染。

memo(Component, arePropsEqual?) 使用 memo 将组件包装起来&#xff0c;以获得该组件的一个 记忆化 版本。通常情况下&#xff0c;只要该组件的 props 没有改变&#xff0c;这个记忆化版本就不会在其父组件重新渲染时重新渲染。但 React 仍可能会重新渲染它&#xff1a;记忆化…

OpenAI新研究破解GPT-4大脑,分解1600万个特征打开“黑匣子”,Ilya 、Jan Leike也参与了!

6月7日凌晨&#xff0c;OpenAI在官网发布了一个新的研究成果&#xff0c;首次破解GPT-4的神经网络活动。通过改进大规模训练稀疏自动编码器将GPT-4的内部表示分解为 1600 万个特征。而且&#xff0c;前段时间离职的Ilya Sutskever、Jan Leike也是作者之一&#xff01; 这不是破…

计算机专业本科就业还是考研?考研有哪些热门方向?

考研并不是一个逃避就业的避难所&#xff0c;也不是一个简单的提升待遇的手段。考研是提升自我的途径&#xff0c;特别是对于那些对特定技术领域有浓厚兴趣并愿意深入研究的人来说 一个本科生能够认真学三年&#xff0c;那么他们所掌握的技能和知识不应该逊色于那些通过短期培…