【微服务-链路跟踪】Spring Cloud Sleuth核心技术(上)

在前面几篇文章中,我们主要介绍了基于 Sentinel 如何对微服务架构提供限流、熔断保护。从本篇开始,我们继续完善微服务架构,通过介绍链路跟踪原理和基于SpringCloud Sleuth实现链路跟踪。

一、微服务链路跟踪原理

我们先看一个图,大家都知道在微服务架构下,系统的功能是由大量的微服务协调组成的,例如:电商创建订单业务就需要订单服务、库存服务、支付服务、短信通知服务逐级调用才能完成。而每个服务可能是由不同的团队进行开发,部署在成百上千台服务器上。

如此复杂的消息传递过程,当系统发生故障的时候,就需要一种机制对故障点进行快速定位,确认是哪个服务出了问题,链路追踪技术由此而生。

**所谓的链路追踪,就是运行时通过某种方式记录下服务之间的调用过程,在通过可视化的 UI 界面帮研发运维人员快速定位到出错点。**引入链路追踪,是微服务架构运维的底层基础,没有它,运维人员就像盲人摸象一样,根本无法了解服务间通信过程。

Spring Cloud 标准生态下内置了 Sleuth 这个组件,它通过扩展 Logging 日志的方式实现微服务的链路追踪。说起来比较晦涩,咱们看一个实例就明白了,在标准的微服务下日志产生的格式是:

2024-03-21 17:00:33.441 INFO [nio-7000-exec-2] c.netflix.config.ChainedDynamicProperty  : Flipping property: b-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647

但是当引入 Spring Cloud Sleuth 链路追踪组件后就会变成下面的格式

2024-03-21 17:00:33.441  INFO [a-service,5f70945e0eefa832,5f70945e0eefa832,true] 18404 --- [nio-7000-exec-2] c.netflix.config.ChainedDynamicProperty  : Flipping property: b-service.ribbon.ActiveConnectionsLimit to use NEXT property: niws.loadbalancer.availabilityFilteringRule.activeConnectionsLimit = 2147483647//比较后会发现,在原有日志中额外附加了下面的文本[a-service,5f70945e0eefa832,5f70945e0eefa832,true]

这段文本就是 Sleuth 在微服务日志中附加的链路调用数据,它的格式是固定的,包含以下四部分:

[微服务 Id,TraceId,SpanId,isExport]

我们来介绍一下这四部分的含义:

  • 微服务ID:指明日志是由哪个微服务产生的。

  • TraceId:轨迹编号。一次完整的业务处理过程被称为轨迹,例如:实现登录功能需要从服务 A 调用服务 B,服务B再调用服务 C,那这一次登录处理的过程就是一个轨迹,从前端应用发来请求到接收到响应,每一次完整的业务功能处理过程都对应唯一的 TraceId。

  • SpanId:步骤编号。刚才要实现登录功能需要从服务 A 到服务 C 涉及 3 个微服务处理,按处理前后顺序,每一个微服务处理时日志都被赋予不同的 SpanId。一个 TraceId 拥有多个 SpanId,而 SpanId 只能隶属于某一个 TraceId。

  • 导出标识:当前这个日志是否被导出,该值为 true 的时候说明当前轨迹数据允许被其他链路追踪可视化服务收集展现。

知道含义之后,我们来模拟一下上述业务逻辑执行的数据跟踪实例:

服务 A -> 服务 B -> 服务 C的调用链路,下面是分别产生的日志

#服务 A 应用控制台日志2024-03-21 22:16:54.394 DEBUG [a-service,e8ca7047a782568b,e8ca7047a782568b,true] 21320 --- [nio-7000-exec-1] org.apache.tomcat.util.http.Parameters   : ...#服务 B 应用控制台日志2024-03-21 22:16:54.402 DEBUG [b-service,e8ca7047a782568b,b6aa80fb33e71de6,true] 21968 --- [nio-8000-exec-2] org.apache.tomcat.util.http.Parameters   : ...#服务 C 应用控制台日志2024-03-21 22:16:54.405 DEBUG [c-service,e8ca7047a782568b,537098c59827a242,true] 17184 --- [nio-9000-exec-2] org.apache.tomcat.util.http.Parameters   : ...

可以发现,在 DEBUG 级别下链路追踪数据被打印出来,按调用时间先后顺序分别是 A 到 C 依次出现。因为是一次完整业务处理,TraceId 都是相同的,SpanId 却各不相同,这些日志都已经被 Sleuth 导出,可以被 ZipKin 收集展示(ZipKin我们后面会聊到,感兴趣的记得关注哦)。

下面咱们通过实例讲解如何在微服务架构中进行链路追踪。

二、微服务整合Sleuth

1、创建微服务

创建 a-service、b-service、c-service 三个 Spring Boot 工程,pom.xml 依赖如下:

<!--Spring Web应用 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--Nacos 客户端 --><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--服务间通信组件OpenFeign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId><version>2.2.6.RELEASE</version></dependency>c-service的pom.xml依赖如下:<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>

因为调用关系是服务 A 调用服务 B,服务 B 调用服务 C,所以在 A、B 两个服务中需要额外依赖 OpenFeign 实现服务间通信。

2、配置微服务的application.yml文件

server:port: 7000 #a:7000/b:8000/c:9000 spring:cloud:nacos:discovery:server-addr: 106.14.221.171:8848username: nacospassword: nacosapplication:name: a-service #a-service/b-service/c-servicelogging:level:root: debug #为演示需要,开启debug级别日志

3、模拟业务逻辑

这里贴出来三个微服务的业务逻辑:

  • c-service:
SampleController,methodC方法产生响应字符串“-> Service C”,方法映射地址“/c”@RestControllerpublic class SampleController {@GetMapping("/c")public String methodC(){String result = " -> Service C";return result;}}
  • b-service:
    CServiceFeignClient 通过 OpenFeign 实现了 C 服务的通信客户端,方法名为 methodC。
@FeignClient("c-service")public interface CServiceFeignClient {@GetMapping("/c")public String methodC();}

SampleController 通过 methodB 方法调用 methodC 的同时为响应附加的字符串“-> Service B”,方法映射地址“/b”。

@Controllerpublic class SampleController {@Resourceprivate CServiceFeignClient cService;@GetMapping("/b")@ResponseBodypublic String methodB(){String result = cService.methodC();result = " -> Service B" + result;return result;}}
  • a-service:
BServiceFeignClient通过OpenFeign实现了B服务的通信客户端,方法名为methodB@FeignClient("b-service")public interface BServiceFeignClient {@GetMapping("/b")public String methodB();}

SampleController 通过 methodA 方法调用 methodB 的同时,成为响应附加的字符串“-> Service A”,方法映射地址“/a”。

@RestControllerpublic class SampleController {@Resourceprivate BServiceFeignClient bService;@GetMapping("/a")public String methodA(){String result = bService.methodB();result = "-> Service A" + result;return result;}}

这样一个完整的调用链路已形成。在 3 个服务实例启动后,访问 A 实例

http://localhost:7000/a 得到运行结果-> ServiceA -> Service B -> Service C

4、引入Sleuth

可以看到 ABC 三个服务按前后顺序依次产生结果,但目前在日志中并没有包含任何链路追踪数据,那如何引入 Sleuth 呢?
只需要打开三个服务工程的 pom.xml 文件分别引入 spring-cloud-starter-sleuth 依赖。

<!--添加Sleuth依赖 --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId><version>2.2.6.RELEASE</version></dependency>

加入依赖后,重启服务,无须做任何额外设置,Spring Cloud Sleuth 便自动为日志增加了链路追踪数据

#服务 A 应用控制台日志,已附加链路追踪数据2024-03-21 22:16:54.394 DEBUG [a-service,e8ca7047a782568b,e8ca7047a782568b,true] 21320 --- [nio-7000-exec-1] org.apache.tomcat.util.http.Parameters   : ...#服务 B 应用控制台日志2024-03-21 22:16:54.402 DEBUG [b-service,e8ca7047a782568b,b6aa80fb33e71de6,true] 21968 --- [nio-8000-exec-2] org.apache.tomcat.util.http.Parameters   : ...#服务 C 应用控制台日志2024-03-21 22:16:54.405 DEBUG [c-service,e8ca7047a782568b,537098c59827a242,true] 17184 --- [nio-9000-exec-2] org.apache.tomcat.util.http.Parameters   : ...

虽然数据已产生,但如果在生产环境靠人工组织数以万计的链路日志显然不现实,我们还需要部署**链路追踪数据的分析工具 ZipKin **来简化这个过程。

ZipKin部署及使用,我们下篇文章再接着聊

文章将持续更新,欢迎关注公众号:服务端技术精选。欢迎点赞、关注、转发

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于RTThread的学习(三):正点原子潘多拉 QSPI 通信 W25Q128 实验

1、基于芯片创建工程 2、QSPI配置 2.1、RTThing_setting 设置组件 2.2、配置board.h 文件 2.3、cubemx生成QSPI的硬件初始化代码&#xff1b;HAL_QSPI_MapInit; 这里注意&#xff1a;你所买的开发板对应的qspi 连接的是否是cubemx 上边显示的&#xff0c;如果不是你需要将引脚…

计算机服务器中了rmallox勒索病毒怎么办?Rmallox勒索病毒解密流程步骤

网络为企业的生产运营提供便利的同时&#xff0c;也为企业的数据安全带来严重威胁。随着互联网技术的不断应用与发展&#xff0c;企业的生产运营离不开网络&#xff0c;利用网络可以开展各项工作业务&#xff0c;极大地方便了企业生产运营&#xff0c;大大提升了企业生产效率&a…

MySQL学习笔记------事务

事务 事务是一组操作的集合&#xff0c;他是一个不可分割的单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败 事务操作 create table account(id int comment ID,name varchar(10) …

前端| 富文本显示不全的解决方法

背景 前置条件&#xff1a;编辑器wangEditor vue项目 在pc端进行了富文本操作&#xff0c; 将word内容复制到编辑器中&#xff0c; 进行发布&#xff0c; pc端正常&#xff0c; 在手机端展示的时候 显示不全 分析 根据h5端编辑器内容的数据展示&#xff0c; 看到有一些样式造…

基于RKNN的YOLOv5安卓Demo

1.简介 基于RKNPU2 SDK 1.6.0版的安卓YOLOv5演示应用程序&#xff0c;选择图片进行对象检测并显示识别结果。 GitHub源码地址&#xff1a;https://github.com/shiyinghan/rknn-android-yolov5 2.实现过程 参考RKNN官方库RKNN Model Zoo提供的YOLOv5对象检测demo&#xff0c…

【Web】CTFSHOW-2023CISCN国赛初赛刷题记录(全)

目录 Unzip BackendService go_session deserbug 主打一个精简 Unzip 进来先是一个文件上传界面 右键查看源码&#xff0c;actionupload.php 直接访问/upload.php&#xff0c;看到后端的源码 就是上传一个压缩包&#xff0c;对其进行解包处理 因为其是在/tmp下执行…

C++ | Leetcode C++题解之第16题最接近的三数之和

题目&#xff1a; 题解&#xff1a; class Solution { public:int threeSumClosest(vector<int>& nums, int target) {sort(nums.begin(), nums.end());int n nums.size();int best 1e7;// 根据差值的绝对值来更新答案auto update [&](int cur) {if (abs(cur…

Qt 中的项目文件解析和命名规范

&#x1f40c;博主主页&#xff1a;&#x1f40c;​倔强的大蜗牛&#x1f40c;​ &#x1f4da;专栏分类&#xff1a;QT❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 目录 一、Qt项目文件解析 1、.pro 文件解析 2、widget.h 文件解析 3、main.cpp 文件解析 4、widget.cpp…

Redis: 持久化

文章目录 一、RDB持久化1、概念2、生成、载入RDB文件3、执行时机&#xff08;1&#xff09; 执行save命令&#xff08;2&#xff09;执行bgsave命令&#xff08;3&#xff09;Redis停机时&#xff08;4&#xff09;触发RDB条件 4、bgsave原理5、小结 二、AOF持久化1、概念2、AO…

element vue 日期时间组件封装

一、背景 年、月、周、日的时间范围类型&#xff0c;选择对应的日期类型&#xff0c;会传参给后端一个dateType参数&#xff0c;用于后端判断&#xff0c;进行数据抽稀。 二、实现效果 三、代码 完整代码&#xff1a; //年月周日&#xff0c;组件封装 //vue3 setup <scrip…

JAVA毕业设计134—基于Java+Springboot+Vue的社区医院管理系统(源代码+数据库+万字论文)

毕设所有选题&#xff1a; https://blog.csdn.net/2303_76227485/article/details/131104075 基于JavaSpringbootVue的社区医院管理系统(源代码数据库万字论文)134 一、系统介绍 本项目前后端分离&#xff0c;分为管理员、用户、医生、前台四种角色 1、用户&#xff1a; 注…

边缘计算采集网关如何助力制造企业解决数采问题-天拓四方

一、企业背景 某大型制造企业&#xff0c;位于国内某经济发达的工业园区内&#xff0c;拥有多个生产线和智能化设备&#xff0c;致力于提高生产效率、降低运营成本。随着企业规模的扩大和生产自动化的推进&#xff0c;该企业面临着海量数据处理、实时响应和网络安全等多重挑战…