当前位置: 首页 > news >正文

【微服务】链路追踪 - Micrometer(day9)

概述

引入

在微服务架构下,客户端一个请求不再仅仅通过一个后端服务和数据库服务就能返回响应,而是通过多个服务节点的协同调用才会产生最终的响应。因此,一个简单的请求就可能会形成一个复杂的分布式服务调用链路,链路中的任何一个服务出错或调用时间过长都会引起整个请求最后的失败。

当服务失败之后,我们就要快速定位具体是哪个服务节点发生了错误,但是我们使用人工一个一个排查就会造成巨大的人力浪费。并且我们还深知,写新需求不复杂,找错误、修bug才最难搞。

基于上述情况,微服务就研发了一套组件来解决上述问题,即分布式链路追踪。所谓的分布式链路追踪,就是将一次分布式请求还原成调用链路,进行日志记录,性能监控并将一次分布式请求的调用情况集中展示。比如请求经过各个服务节点的耗时,请求具体到哪台机器上,每个服务节点的请求状态等。

简单来说,分布式链路追踪就是把一个请求经过的所有节点都记录下来,包括但不限于耗时,父亲节点,节点状态等等。

Micrometer

Micrometer就是分布式链路追踪的落地组件,SpringCloudSleuth是分布式链路追踪的上一代组件。不过由于现在使用的是SpringBoot3以上的版本,因此与Sleuth不再兼容,该篇文章中,主要学的也是Micrometer组件。并且与zipkin相结合使用,下图所示,Micrometer将一次请求经过的路径进行记录,然后交给zipkin进行展现。

原理

一个请求通过一个TraceId来唯一标识,对于每个服务节点来说,都使用SpanId来标识,各个服务节点还会记录一个ParentId。最后通过TraceId、SpanId和ParentId将整条链路进行追踪。

其他组件

Cat:由大众点评开源,基于Java开发的实时应用监控平台,包括实时应用监控、业务监控,集成方案是通过代码埋点的方式来实现监控。比如:拦截器、过滤器等。对代码的侵入性很大、集成成本较高、风险很大。

Zipkin:由Twitter公司开源,开发源代码分布式的跟踪系统,用于收集服务的定时数据,以解决微服务架构中的延迟问题,包括:数据的收集、存储查找和展现,结合SpringCloudSleuth使用较为简单,集成方便,但是功能较简单。

Pinpoint:是一款开源的基于字节码注入的调用链分析,以及应用监控分析工具,特点是支持多种插件,UI功能强大,接入端无代码侵入。

Skywalking:是中国人开源的基于字节码注入的调用链分析,以及应用监控分析工具,特点是支持多种插件,UI功能较强,接入端无代码侵入。

ZipKin

Zipkin是一种分布式链路跟踪系统图形化的工具,Zipkin 是 Twitter 开源的分布式跟踪系统,能够收集微服务运行过程中的实时调用链路信息,并能够将这些调用链路信息展示到Web图形化界面上供开发人员分析,开发人员能够从ZipKin中分析出调用链路中的性能瓶颈,识别出存在问题的应用程序,进而定位问题和解决问题。

简单来说,ZipKin就是用来展示分布式链路追踪的结果,使得开发人员能够轻松便捷的找到问题出现的原因,然后着手解决。

使用官网进行下载:

下载成功之后,直接在其对应页面打开cmd,然后使用java -jar 文件名就可以运行了:

 

 启动之后,进入127.0.0.1:9411/zipkin/看到如下画面,就算启动成功了。

案例代码

在该案例中,共创建了四个服务,链路代码是服务A调用服务B,服务B可以调用服务C和服务D。采用的技术栈有:Nacos、OpenFeign、LoadBalancer以及今天的主角Micrometer和ZipKin。

父工程中引入依赖

            <!--链路追踪--><micrometer-tracing.version>1.2.0</micrometer-tracing.version><micrometer-observation.version>1.12.0</micrometer-observation.version><feign-micrometer.version>12.5</feign-micrometer.version><zipkin-reporter-brave.version>2.17.0</zipkin-reporter-brave.version><!--链路追踪--><!--micrometer-tracing-bom导入链路追踪版本中心  1--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bom</artifactId><version>${micrometer-tracing.version}</version><type>pom</type><scope>import</scope></dependency><!--micrometer-tracing指标追踪  2--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing</artifactId><version>${micrometer-tracing.version}</version></dependency><!--micrometer-tracing-bridge-brave适配zipkin的桥接包 3--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-brave</artifactId><version>${micrometer-tracing.version}</version></dependency><!--micrometer-observation 4--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-observation</artifactId><version>${micrometer-observation.version}</version></dependency><!--feign-micrometer 5--><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-micrometer</artifactId><version>${feign-micrometer.version}</version></dependency><!--zipkin-reporter-brave 6--><dependency><groupId>io.zipkin.reporter2</groupId><artifactId>zipkin-reporter-brave</artifactId><version>${zipkin-reporter-brave.version}</version></dependency>

创建模块

由于这几个模块只用于测试分布式链路追踪,所以四个模块中内容几乎相同。

引入pom文件

四个模块的pom文件几乎相同,只有GAV不太相同,所以我只引入一个,剩下的大家稍稍修改一下就好了。

<?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><parent><groupId>com.wbz</groupId><artifactId>spring-cloud-test</artifactId><version>1.0-SNAPSHOT</version></parent><artifactId>cloud-micrometer-two-8602</artifactId><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--注册中心--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency><!--基础模块--><dependency><groupId>com.wbz</groupId><artifactId>cloud-commons</artifactId><version>1.0-SNAPSHOT</version><exclusions><exclusion><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId></exclusion></exclusions></dependency><!--web--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--负载均衡--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency><!--链路追踪--><!--micrometer-tracing指标追踪  1--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing</artifactId></dependency><!--micrometer-tracing-bridge-brave适配zipkin的桥接包 2--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-tracing-bridge-brave</artifactId></dependency><!--micrometer-observation 3--><dependency><groupId>io.micrometer</groupId><artifactId>micrometer-observation</artifactId></dependency><!--feign-micrometer 4--><dependency><groupId>io.github.openfeign</groupId><artifactId>feign-micrometer</artifactId></dependency><!--zipkin-reporter-brave 5--><dependency><groupId>io.zipkin.reporter2</groupId><artifactId>zipkin-reporter-brave</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-actuator</artifactId></dependency></dependencies></project>

写yml文件

同样,yml文件中也是端口号和服务名不一样,大家自己修改一下就好。

server:port: 8602spring:application:name: cloud-micrometer-two-8602cloud:nacos:discovery:server-addr: 127.0.0.1:8848service: ${spring.application.name}profiles:active: dev# ========================zipkin===================
management:zipkin:tracing:endpoint: http://localhost:9411/api/v2/spanstracing:sampling:probability: 1.0 #采样率默认为0.1(0.1就是10次只能有一次被记录下来),值越大收集越及时。

写启动类

在启动类中,服务1和服务2都要远程调用,所以要加入开启远程调用的注解。当然,服务三和服务四也可以开启,不过要注意服务三和服务四是否有OpenFeign的依赖。

@EnableFeignClients // 远程调用
@SpringBootApplication
public class MicrometerCloudApplication8602 {public static void main(String[] args) {SpringApplication.run(MicrometerCloudApplication8602.class, args);}}

写业务类和远程调用的接口

服务三和服务四

@RestController
@RequestMapping("/three")
public class ThreeController {@GetMapping("/get/three")public String getContent() {return "第三个服务,被第二个服务调用" + '\n';}}
@RestController
@RequestMapping("/four")
public class FourController {@GetMapping("/get/four")public String getContent() {return "第四个服务,被第二个服务调用" + '\n';}}
@FeignClient(value = "cloud-micrometer-three-8603", path = "/three")
public interface MicrometerThreeFeignApi {@GetMapping("/get/three")String getContent();}
@FeignClient(value = "cloud-micrometer-four-8604", path = "/four")
public interface MicrometerFourFeignApi {@GetMapping("/get/four")String getContent();}

服务二

@FeignClient(value = "cloud-micrometer-two-8602", path = "/two")
public interface MicrometerTwoFeignApi {@GetMapping("/get/twoOfOne")String twoOfOne();@GetMapping("/get/twoOfTwo")String twoOfTwo();}
@RestController
@RequestMapping("/two")
public class TwoController {@Resourceprivate MicrometerThreeFeignApi micrometerThreeFeignApi;@Resourceprivate MicrometerFourFeignApi micrometerFourFeignApi;@GetMapping("/get/twoOfOne")public String twoOfOne() {return "第二个服务,被第一个服务调用,然后调用第三个服务" +this.micrometerThreeFeignApi.getContent();}@GetMapping("/get/twoOfTwo")public String twoOfTwo() {return "第二个服务,被第一个服务调用,然后调用第四个服务" +this.micrometerFourFeignApi.getContent();}}

服务一

@RestController
@RequestMapping("/one")
public class OneController {@Resourceprivate MicrometerTwoFeignApi micrometerTwoFeignApi;@GetMapping("/getOneOfOne")public String getOneOfOne() {return "第一个服务,调用第二个服务" + '\n' +this.micrometerTwoFeignApi.twoOfOne();}@GetMapping("/getOneOfTwo")public String getOneOfTwo() {return "第一个服务,调用第二个服务" + '\n' +this.micrometerTwoFeignApi.twoOfTwo();}}

测试

启动服务之后,分别调用127.0.0.1:one/getOneOfOne以及127.0.0.1:one/getOneOfTwo,多调用几次,然后稍等几分钟,再去ZipKin官网看看。

在官网,点击运行查询,就能出现如下结果,也可以点进去详细查看,就是一个请求对应的每个节点的耗时时间等内容。

然后去依赖页面,再次点击运行查询,就会出现一个调用图:

 

当然,在页面当中,还有许多详细信息,就不作过多介绍,不是我不想说,主要我也不知道。所以那些详细信息,就让咋们一起去探索吧,只希望别我毕业了,组件又换了。 


http://www.mrgr.cn/news/47187.html

相关文章:

  • Unity的Transform类
  • 典型的 package.json 文件中的
  • Python进阶-在Ubuntu上部署Flask应用
  • LeetCode432周赛T2,记忆化搜索
  • mermaid大全(语法、流程图、时序图、甘特图、饼图、用户旅行图、类图)
  • 【STM32-学习笔记-1-】GPIO
  • 爸妈用手机有多难?第一条就破防了
  • 如何用往期错题发起一场考试❓
  • Pytest+selenium UI自动化测试实战实例
  • win10电脑导航栏经常卡死改善方法
  • 如何高效进行网络质量劣化分析与流量回溯分析
  • 卷积神经网络细节问题及知识点
  • 领域驱动设计DDD的工作机制
  • 微信服务号灰度测试折叠,看谁该慌了?
  • Facebook直播分析与问题解决策略
  • 【网络】详解TCP协议中的可靠传输
  • 中科星图GVE(案例)——AI提取指定采样区域的建筑物范围
  • Android WebView 与 H5 交互的一些总结
  • @RequestMapping指定请求方式的用法
  • 【优选算法】(第三十二篇)
  • 请用python写一个小程序,把浏览器中打开的页面设置为深色模式
  • Solr简介
  • 如何高效部署SD-WAN及是否需要路由器?
  • windows 11 PE 制作及应用
  • 不同操作系统间conda环境迁移出现ResolvePackageNotFound错误
  • JavaScript 运算符全知道