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

【微服务】springcloud集成sleuth与zipkin实现链路追踪

目录

一、前言

二、分布式链路调用问题

三、链路追踪中的几个概念

3.1 什么是链路追踪

3.2 常用的链路追踪技术

3.3 链路追踪的几个术语

3.3.1 span

​编辑

3.3.2 trace

3.3.3 Annotation

四、sluth与zipkin概述

4.1 sluth介绍

4.1.1 sluth是什么

4.1.2 sluth核心功能

4.1.3 sluth工作原理

4.2 zipkin介绍

4.2.1 zipkin是什么

4.2.2 zipkin工作原理与核心组件

4.3 sluth与zipkin的关系

五、微服务集成Sleuth

5.1 Sleuth集成过程

5.1.1 导入依赖

5.1.2 添加注解

5.1.3 参数说明

六、微服务集成sleuth + zipkin

6.1 部署zipkin服务端

6.1.2 访问UI界面

6.2 zipkin数据持久化

6.2.1 获取zipkin的建表sql

6.2.2 重启zipkin服务

6.3 springcloud客户端集成zipkin

6.3.1 导入zipkin依赖

6.3.2 添加配置文件

6.3.3 重启服务并触发接口调用

七、写在文末


一、前言

在springcloud技术栈构建的微服务架构体系中,一旦微服务数量越来越多,服务之间的调用链路也必然越来越复杂,遇到问题时,排查难度也会相应增加。

二、分布式链路调用问题

如下图所示,为模拟一个微服务架构的系统在真实线上部署的场景,客户端发出的一个请求,通过网关之后,在内部处理请求时,可能经历了非常复杂的互相调用,试想,现在某个链路突然发生异常,对于开发人员来说,是不是有点摸不着头脑。

以上只是众多的微服务调用链路中相对比较简单的一种,通常来说,在分布式调用中,一个由客户端发起的请求,在后端系统中会经过多个不同的微服务调用来协同产生最后的请求结果。

在复杂的微服务架构系统中,几乎每一个请求都会形成一条复杂的分布式服务调用链路。在每条链路中,任何一个依赖服务出现延迟过高,或错误时都有可能造成请求最后的失败。这时对于每个请求全链路调用的跟踪就变得非常重要。

通过实现对请求调用的跟踪,可以帮助开发人员快速的定位错误根源,以及监控分析每条请求链路上的性能瓶颈等。

在开源的分布式链路追踪解决方案中,以springcloud生态来说,针对微服务链路追踪这个问题,Spring Cloud Sleuth提供了一套完整的解决方案。

三、链路追踪中的几个概念

3.1 什么是链路追踪

链路追踪一词最早在2010年提出,由谷歌发表的一篇关于大规模分布式系统跟踪的论述,介绍了谷歌自研的分布式链路追踪的实现原理。

侠义上理解链路追踪,就是指一次任务从开始到结束,期间调用的所有系统以及耗时(时间跨度)都可以完整的记录下来。

广义上讲,链路追踪是指在分布式系统中,将一次请求的处理过程进行记录并聚合展示的一种方法。目的是将一次分布式请求的调用情况集中在一处展示,如各个服务节点上的耗时、请求具体到达哪台机器上、每个服务节点的请求状态等。这样就可以轻松了解一个请求在系统中的完整生命周期,包括经过的服务、调用的操作以及每个操作的延迟等。

通过链路追踪,可以更好地理解系统的性能瓶颈、找出问题的根源以及优化系统的性能。

3.2 常用的链路追踪技术

目前,链路追踪方案像Google的Dapper,阿里的鹰眼,大众点评的CAT,Twitter的Zipkin,LINE的pinpoint,国产的skywalking等。市面上的全链路监控理论模型大多都是借鉴Google Dapper论文,这里列举下面几种:

  • cat:由大众点评开源,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控。集成方案是通过代码埋点的方式实现监控。比如:拦截器,过滤器等。对业务代码具有一定的侵入性,集成成本较大,风险较高;
  • Zipkin :由Twitter公司开源,开放源代码分布式的跟踪系统,用于收集服务的定时数据,以解决微服务架构中的延迟问题,包括:数据的收集、存储、查找和展现,通常结合springcloud-sleuth一起使用比较简单,集成方便,但是功能相对简单;
  • Pinpoint :一款对Java编写的大规模分布式系统的APM工具,由韩国人开源的分布式跟踪组件,其底层基于字节码的注入进行调用链的分析,以及应用监控分析工具,其特点是支持多种插件,UI功能强大,接入端无代码前任;
  • Skywalking :国产的优秀APM组件,是一个对JAVA分布式应用程序集群的业务运行情况进行追踪、告警和分析的系统,基于字节码注入调用链分析,以及应用监控分析工具,特点是支持多种插件,UI功能强大,接入端无代码侵入,目前已加入apache孵化;
  • sleuth,由springcloud提供的分布式系统中链路追踪的解决方案;

下面结合两种使用较多的链路追踪工具zipkinSkywalking 进行对比说明

类型zipkinSKYwalking
基本原理拦截请求,发送(HTTP,mq)数据至zipkin服务java探针,字节码增强
接入方式基于linkerd或者sleuth方式,引入配置即可Java agent字节码
支持OpenTracing
颗粒度接口级(类级别)方法级
存储ES,mysql,Cassandra,内存ES,H2,TIDB
agent到collector的协议http,MQhttp,gRPC

3.3 链路追踪的几个术语

在链路追踪的解决方案中,不管是哪一种,基本上各个组件底层都使用了相同的规范,其中涉及到下面几个非常重要的术语。

3.3.1 span

span代表一组基本的工作单元,一次单独的调用链可称为一个span。通俗理解,span就是一次请求信息,当发送一个远程调用时就会产生一个Span,Span 由一个64位ID唯一标识的。

举例来说,为统计一个请求中各处理单元的延迟,当请求到达服务的各个组件时,通过一个唯一标识(SpanId)来标记它的开始、具体过程和结束。通过SpanId的开始和结束时间戳,就能统计该span的调用时间,除此之外,我们还可以获取如事件的名称。请求信息等元数据。

如下,图中一个矩形框就是一个 Span,前端从发出请求到收到回复就是一个 Span。

3.3.2 trace

由一组TraceId相同的Span串联形成的一个树状结构。一个trace可认为是一次完整的链路,内部包含多个span,trace和span之间是一对多的关系。而span与span之间存在父子级关系。

为实现请求跟踪,当请求到达分布式系统的入口端点时,只需要服务跟踪框架为该请求创建一个唯一的标识(即TraceId),同时在分布式系统内部流转的时候,框架始终保持传递该唯一值,直到整个请求的返回。那么我们就可以使用该唯一标识将所有的请求串联起来,形成一条完整的请求链路。

举个例子:客户端调用服务 A 、服务 B 、服务 C 、服务 F,而每个服务例如 C 就是一个 Span,如果在服务 C 中另起线程调用了 D,那么 D 就是 C 的子 Span,如果在服务 D 中另起线程调用了 E,那么 E 就是 D 的子 Span,这个 C -> D -> E 的链路就是一条 Trace。如果链路追踪系统做好了,链路数据有了,借助前端解析和渲染工具,可以达到下图中的效果:

3.3.3 Annotation

Annotation 用于记录一段时间内的事件,内部使用的重要注释:

  • cs(Client Send),客户端发起一个请求,这个 annotation 描述了这个 span 的开始;
  • sr(Server Received),服务端获得请求并准备开始处理它,如果 sr 减去 cs 时间戳便可得到网络延迟;
  • ss(Server Send),请求处理完成(当请求返回客户端),如果 ss 减去 sr 时间戳便可得到服务端处理请求需要的时间;
  • cr(Client Reveived),表示 span 结束,客户端成功接收到服务端的回复,如果 cr 减去 cs 时间戳便可得到客户端从服务端获取回复的所有所需时间;

四、sluth与zipkin概述

4.1 sluth介绍

4.1.1 sluth是什么

Spring Cloud 微服务治理框架中的一个组件,专门用于记录链路数据的开源组件,官网地址

4.1.2 sluth核心功能

sluth提供的核心功能主要如下:

  • 链路追踪:通过 Sleuth 可以很清楚的看出一个请求都经过了那些服务,可以很方便的理清服务间的调用关系等;
  • 性能分析:通过 Sleuth 可以很方便的看出每个采样请求的耗时,分析哪些服务调用比较耗时,当服务调用的耗时随着请求量的增大而增大时, 可以对服务的扩容提供一定的提醒;
  • 数据分析,优化链路:对于频繁调用一个服务,或并行调用等,可以针对业务做一些优化措施;
  • 可视化错误:对于程序未捕获的异常,可以配合 Zipkin 查看;

4.1.3 sluth工作原理

下面这张图详细说明了sleuth在工作过程中其内部的运行原理,理解了这张图的原理,不仅明白了sleuth是如何运行的,也对链路追踪中的几个概念也会有更深刻的理解。

关于这张图的调用过程做如下说明:

  • 从左到右,展示了客户端从发送一个请求,到最终请求响应结果的完整链路;
  • 如果想知道一个接口在哪个环节出现了问题,就必须清楚该接口调用了哪些服务,以及调用的顺序,如果把这些服务串起来,看起来就像链条一样,我们称之为调用链;
  • 想要实现调用链,就要为每次调用做个标识,然后将服务按标识大小排列,可以更清晰地看出调用顺序,我们暂且将该标识命名为 spanid;
  • 实际场景中,我们需要知道某次请求调用的情况,所以只有spanid还不够,得为每次请求做个唯一标识,这样才能根据标识查出本次请求调用的所有服务,而这个标识我们命名为 traceid;
  • 现在根据 spanid 可以轻易地知道被调用服务的先后顺序,但无法体现调用的层级关系,正如下图所示,多个服务可能是逐级调用的链条,也可能是同时被同一个服务调用;
  • 所以应该每次都记录下是谁调用的,我们用 parentid 作为这个标识的名字;
  • 到现在,已经知道调用顺序和层级关系了,但是接口出现问题后,还是不能找到出问题的环节,如果某个服务有问题,那个被调用执行的服务一定耗时很长,要想计算出耗时,上述的三个标识还不够,还需要加上时间戳,时间戳可以更精细一点,精确到微秒级;

其实 span 内除了记录这几个参数之外,还可以记录一些其他信息,比如发起调用服务名称、被调服务名称、返回结果、IP、调用服务的名称等,最后,我们再把相同 parentid 的 span 信息合成一个大的 span 块,就完成了一个完整的调用链。

4.2 zipkin介绍

4.2.1 zipkin是什么

zipkin是一款开源的分布式实时数据追踪系统(Distributed Tracking System),基于 Google Dapper的论文设计而来,由 Twitter 公司开发贡献。它有助于收集对服务架构中的延迟问题进行故障排除所需的计时数据。功能包括收集和查找这些数据。

zipkin是一个开放源代码分布式的跟踪系统,它可以帮助收集服务调用中的时间数据,以解决微服务架构中的延迟问题。具体来说,包括数据收集、存储、查找和展现。

当微服务接入zipkin之后,每个服务向zipkin报告计时数据,zipkin会根据调用关系通过Zipkin UI生成依赖关系图,展示多少跟踪请求经过了哪些服务,该系统让开发者可通过一个web前端轻松地收集和分析数据,可非常方便的监测系统中存在的瓶颈。

下面是一张关于zipkin的原理图,从图中不难发现,在真实的环境中,zipkin主要是承担收集各个服务上报过来的信息,比如日志、服务链路等数据,经过内部的处理之后,通过ui界面进行展现。

4.2.2 zipkin工作原理与核心组件

下面是zipkin的工作原理图

或者通过下面这张运行原理图可以以全局的视角来了解zipkin

从上面的图中,可以发现zipkin在运行过程中,其核心组件主要包括下面几种:

Collector:信息收集器

主要用于处理从外部系统发送过来的跟踪信息,将这些信息转换为Zipkin内部处理的Span格式,以支持后续的存储、分析、展示等功能。

Storage:数据存储组件

主要对处理收集器接收到的跟踪信息,默认会将这些信息存储在内存中,我们也可以修改此存储策略,通过使用其他存储组件将跟踪信息存储到 数据库或es 中。

RESTful API:API组件

主要用于提供外部访问接口,比如给客户端展示跟踪信息,或是外接系统访问以实现监控等。

Web UI:UI组件  

基于API组件实现的上层应用。通过UI组件用户可以方便而有直观地查询和分析跟踪信息。

小结:

1)Zipkin 分两端,一个是 Zipkin 服务端,一个是 Zipkin 客户端,客户端也就是微服务应用;

2)客户端会配置服务端的 URL 地址,一旦发生服务间的调用的时候,会被配置在微服务里面的 Sleuth 的监听器监听,并生成相应的 Trace 和 Span 信息发送给服务端;

3)发送的方式有两种,一种是消息总线的方式如 RabbitMQ 发送,还有一种是 HTTP 报文的方式发送;

4.3 sluth与zipkin的关系

通过上面的介绍我们了解到,Sleuth是将每个请求从开始调用到结束过程中的每一步都进行记录, 但这些信息都是分散存在的,通过以日志格式输出出来,真正进行问题分析定位时并不方便,此时就需要有一个工具可以将这些分散的信息进行收集和汇总,并且能显示可视化结果,便于分析和定位。

有了zipkin之后,sleuth的只需要把链路追踪的元数据信息上报给zipkin,由zipkin进行存储并将链路信息以可视化的方式进行呈现。

五、微服务集成Sleuth

sleuth可以单独在springboot项目中使用,也可以在springcloud、dubbo中进行集成,下面介绍sleuth最简单的集成方式。

5.1 Sleuth集成过程

文档地址:官方文档地址

git地址:sleuth git地址

5.1.1 导入依赖

maven中导入sleuth依赖

<!-- spring cloud sleuth 依赖 -->
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-sleuth</artifactId>
</dependency>

5.1.2 添加注解

以之前整合的一个springcloud微服务为例进行说明,最简单的集成方式是,只需要在需要进行链路追踪的类上面添加 @Slf4j注解即可,如下,服务的调用链路为:order -> user,我们分别在需要调用的类上面添加注解;

用户微服务中添加注解,在方法的关键入口添加日志输出,默认sleuth追踪info级别的日志

@RestController
@RequestMapping("/user")
@Slf4j
public class UserController {@Autowiredprivate UserService userService;//http:localhost:9002/user/getById?id=001@GetMapping("/getById")public User getById(@RequestParam String id) {log.info("根据ID获取用户信息");return userService.getById(id);}
}
@Slf4j
@Service
public class UserServiceImpl  implements UserService {@Autowiredprivate RedisTemplate<String, Object> redisTemplate;@Autowiredprivate UserMapper userMapper;@Overridepublic User getById(String id) {log.info("[用户服务] 基于 id 查询用户信息:{}", id);String key = "sw:users:" + id;Object json = redisTemplate.opsForValue().get(key);if (json != null) {log.info("[用户服务] redis 中查询到用户信息:key={}, json={}", key, json);return JSON.parseObject(json.toString(), User.class);}User user = userMapper.getById(id);if (user != null) {log.info("[用户服务] redis 中不存在,从数据库查到数据并缓存:{}", user);redisTemplate.opsForValue().set(key, user, 2, TimeUnit.HOURS);return user;}log.warn("[用户服务] 基于 id 查询用户失败,用户不存在:{}", id);return null;}
}

order微服务中添加注解

@RequestMapping("/order")
@RestController
@Slf4j
public class OrderController {@Autowiredprivate OrderService orderService;//localhost:9003/order/getById?id=001@GetMapping("/getById")public Object getById(@RequestParam String id) {log.info("根据ID获取订单");return orderService.getById(id);}
}
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {@Autowiredprivate  UserFeignService userFeignService;@Overridepublic Map getById(String id) {log.info("[订单服务] 基于 id 查询订单详情:{}", id);Map map = new HashMap();Order order = new Order();order.setOrderId("0002");order.setProductId("0001");order.setProductName("小米手机");map.put("order",order);User user = userFeignService.getById("001");map.put("user",user);return map;}
}

重启两个微服务模块,然后调用一下接口

5.1.3 参数说明

接口调用成功后,我们观察控制台输出日志信息,order模块输出日志信息如下:

user模块输出的日志信息如下:

关于日志信息,做如下几点说明:

  • 第一个值,spring.application.name 的值;
  • 第二个值,sleuth生成的一个ID,即traceId,用来标识一条请求链路,一条请求链路中包含一个traceId,多个spanId;
  • 第三个值,spanId,基本工作单元,获取元数据,比如发送一个http;
  • 第四个值,true/false,表示信息输出到zipkin中收集和展示;

六、微服务集成sleuth + zipkin

通过上文了解到,zipkin是一款用于做实时链路数据追踪的应用,通过可视化的方式展现从服务中上报的日志等链路追踪数据,便于问题的排查定位和分析,更加的人性化。

通常,以springcloud技术栈的微服务中,通常是将sleuth 搭配zipkin一起使用。当然也可以单独在springboo工程中接入zipkin。

6.1 部署zipkin服务端

zipkin服务端是一个独立的可执行的 jar 包,jar包下载地址:

1、官网下载,OpenZipkin · A distributed tracing system

2、ftp下载,zipkin各版本下载地址

这里我下载 2.22.1的版本的jar包

下载之后,不管是本地还是在linux服务器上,最简单的方式,直接使用下面的命令启动即可

java -jar zipkin-server-2.20.1-exec.jar

6.1.2 访问UI界面

服务启动之后,通过9411端口可以直接访问zipkin的web-ui界面,如下图所示,后面当微服务接入zipkin之后,一旦发生服务间的调用将会展示出调用链路相关信息

6.2 zipkin数据持久化

Zipkin 默认将监控数据存储在内存中,很显然,如果 Zipkin 挂掉或重启的话,监控数据就会丢失。所以生产中,肯定是不能直接这样使用,需要对Zipkin的监控数据进行持久化存储。zipkin提供了多种数据持久化存储的方式:

  • 内存(默认);
  • mysql(推荐);
  • es(推荐);
  • Cassandra;

下面以mysql为例进行说明

6.2.1 获取zipkin的建表sql

脚本下载地址在 github zipkin项目里的 zipkin-storage/mysql-v1/src/main/resounce 目录下

mysql脚本地址

为例方便使用,下面贴出完整的sql

--
-- Copyright 2015-2019 The OpenZipkin Authors
--
-- Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
-- in compliance with the License. You may obtain a copy of the License at
--
-- http://www.apache.org/licenses/LICENSE-2.0
--
-- Unless required by applicable law or agreed to in writing, software distributed under the License
-- is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
-- or implied. See the License for the specific language governing permissions and limitations under
-- the License.
--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,然后执行上面的sql创建表

6.2.2 重启zipkin服务

使用下面的命令重新启动zipkin服务

java -jar zipkin-server-2.22.1-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=IP地址 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=密码

启动之后再次访问,仍然可以正常访问ui页面

6.3 springcloud客户端集成zipkin

上面的环境准备好之后,相当于是搭建了zikpkin的服务端,接下来就可以在springcloud微服务工程中(客户端)集成zpikin,将客户端的服务调用链路信息上报zipkin了,参考下面的操作步骤

6.3.1 导入zipkin依赖

sleuth的依赖仍然保留,同时添加zipkin的依赖

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

6.3.2 添加配置文件

在工程的配置文件中添加如下关于zipkin和sleuth的配置信息,如果是云服务器,需要提前开通9411的防火墙端口

server:port: 9002spring:application:name: user-servicezipkin:base-url: http://127.0.0.1:9411sleuth:sampler:probability: 1cloud:nacos:discovery:server-addr: nacos地址:8848

6.3.3 重启服务并触发接口调用

确保zipkin服务已经启动,然后启动user和order两个服务,并调用下面的获取订单接口

调用成功后,在zipkin的ui界面上就能看到调用的链路信息了,如下图所示:

也可以点击进去,进一步查看,通过其他维度检查这个调用链路的详细信息,比如中间经历了哪些步骤,各个链路的耗费时间

也可以切换到依赖视图,以拓扑图的形式展示服务的调用链路情况

七、写在文末

本文详细介绍了sleuth和zipkin的使用,在springcloud的微服务生态中,这两个组件的搭配可以快速实现服务链路的追踪,接入简单,对服务的可观测性来说是一个很好的补充,而zipkin的思想,也影响甚至促成了应用可观测领域很多解决方案的诞生,有必要深入学习和掌握其适用场景,本篇到此结束感谢观看。

相关文章:

【微服务】springcloud集成sleuth与zipkin实现链路追踪

目录 一、前言 二、分布式链路调用问题 三、链路追踪中的几个概念 3.1 什么是链路追踪 3.2 常用的链路追踪技术 3.3 链路追踪的几个术语 3.3.1 span ​编辑 3.3.2 trace 3.3.3 Annotation 四、sluth与zipkin概述 4.1 sluth介绍 4.1.1 sluth是什么 4.1.2 sluth核心…...

数学建模-预测人口数据

目录 中国09~18年人口数据 创建时间 绘制时间序列图 使用专家建模器 得到结果 预测结果 残差的白噪声检验 中国09~18年人口数据 创建时间 路径&#xff1a;数据-> 定义日期和时间 绘制时间序列图 使用专家建模器 看看spss最终判断是那个模型最佳的契合 得到结果 预…...

SpringBoot 集成 Canal 基于 MySQL 做数据同步

一、canal 组件关系 下载地址&#xff1a;https://github.com/alibaba/canal/releases/download/canal-1.1.7/ 这里面主要的有两个 canal.deployer-1.1.7.tar.gz 和 canal.adapter-1.1.7.tar.gz&#xff0c;canal.admin-1.1.7.tar.gz 是一个监控服务&#xff0c;可选&#xf…...

【CVE-2022-22733漏洞复现】

Apache ShardingSphere ElasticJob-UI漏洞 漏洞编号:CVE-2022-22733 文档说明 本文作者:SwBack 创作时间:2024/1/21 19:19:19 知乎:https://www.zhihu.com/people/back-88-87 CSDN:https://blog.csdn.net/qq_30817059 百度搜索: SwBack漏洞描述 Apache ShardingSphere Elast…...

Python爬虫---scrapy框架---当当网管道封装

项目结构&#xff1a; dang.py文件&#xff1a;自己创建&#xff0c;实现爬虫核心功能的文件 import scrapy from scrapy_dangdang_20240113.items import ScrapyDangdang20240113Itemclass DangSpider(scrapy.Spider):name "dang" # 名字# 如果是多页下载的话, …...

【机器学习】机器学习四大类第01课

一、机器学习四大类 有监督学习 (Supervised Learning) 有监督学习是通过已知的输入-输出对&#xff08;即标记过的训练数据&#xff09;来学习函数关系的过程。在训练阶段&#xff0c;模型会根据这些示例调整参数以尽可能准确地预测新的、未见过的数据点的输出。 实例&#x…...

下述默认构造函数有什么问题?

12.4 // points to string allocated by new // holds length of string 独立的、相同的数据,而不会重叠。由于同样的原因,必须定义赋值操作符。对于每一种情况,最终目的 都是执行深度复制,也就是说,复制实际的数据,而不仅仅是复制指向数据的指针。 对象的存储持续性为自动或…...

vite和mockjs配合使用

vite mockjs 当后端还没准备完成之前&#xff0c;前端可以使用 mock 模拟后端响应&#xff0c;提高开发效率 1、安装插件 使用 vite-plugin-mock 插件&#xff0c;配合mockjs完成项目的 mock 配置 npm install mockjs vite-plugin-mock2、vite配置插件 在 vite.config.js…...

【数据结构】常见八大排序算法总结

目录 前言 1.直接插入排序 2.希尔排序 3.选择排序 4.堆排序 5.冒泡排序 6.快速排序 6.1Hoare版本 6.2挖坑法 6.3前后指针法 6.4快速排序的递归实现 6.5快速排序的非递归实现 7.归并排序 8.计数排序&#xff08;非比较排序&#xff09; 9.补充:基数排序 10.总结…...

系统学英语 — 句法 — 常规句型

目录 文章目录 目录5 大基本句型复合句型主语从句宾语从句表语从句定语从句状语从句同位语从句补语从句 谓语句型 5 大基本句型 主谓&#xff1a;主语发出一个动作&#xff0c;例如&#xff1a;He cried.主谓宾&#xff1a;we study English.主系表&#xff1a;主语具有某些特…...

Github操作网络异常笔记

Github操作网络异常笔记 1. 源由2. 解决2.1 方案一2.2 方案二 3. 总结 1. 源由 开源技术在国内永远是“蛋疼”&#xff0c;这些"政治"问题对于追求技术的我们&#xff0c;形成无法回避的障碍。 $ git pull ssh: connect to host github.com port 22: Connection ti…...

Vue3新特性defineModel()便捷的双向绑定数据

官网介绍 传送门 配置 要求&#xff1a; 版本&#xff1a; vue > 3.4(必须&#xff01;&#xff01;&#xff01;)配置&#xff1a;vite.config.js 使用场景和案例 使用场景&#xff1a;父子组件的数据双向绑定&#xff0c;不用emit和props的繁重代码 具体案例 代码实…...

vue列表飞入效果

效果 实现代码 <template><div><button click"add">添加</button><TransitionGroup name"list" tag"ul"><div class"list-item" v-for"item in items" :key"item.id">{{ i…...

C语言·预处理详解

1. 预定义符号 C语言设置了一些预定义符号&#xff0c;可以直接使用&#xff0c;预定义符号也是在预处理期间处理的 __FILE__ 进行编译的源文件 __LINE__ 文件当前的行号 __DATE__ 文件被编译的日期 __TIME__ 文件被编译的时间 __STDC__ 如果编译器遵循ANSI C&#xff0c;…...

服务器与普通电脑的区别,普通电脑可以当作服务器用吗?

服务器在我们日常应用中非常常见&#xff0c;手机APP、手机游戏、PC游戏、小程序、网站等等都需要部署在服务器上&#xff0c;为我们提供各种计算、应用服务。服务器也是计算机的一种&#xff0c;虽然内部结构相差不大&#xff0c;但是服务器的运行速度更快、负载更高、成本更高…...

数字身份所有权:Web3时代用户数据的掌控权

随着Web3时代的来临&#xff0c;数字身份的概念正焕发出崭新的光芒。在这个数字化的时代&#xff0c;用户的个人数据变得愈加珍贵&#xff0c;而Web3则为用户带来了数字身份所有权的概念&#xff0c;重新定义了用户与个人数据之间的关系。本文将深入探讨Web3时代用户数据的掌控…...

python爬虫如何写,有哪些成功爬取的案例

编写Python爬虫时&#xff0c;常用的库包括Requests、Beautiful Soup和Scrapy。以下是三个简单的Python爬虫案例&#xff0c;分别使用Requests和Beautiful Soup&#xff0c;以及Scrapy。 1. 使用Requests和Beautiful Soup爬取网页内容&#xff1a; import requests from bs4 …...

PLC物联网网关BL104实现PLC协议转MQTT、OPC UA、Modbus TCP

随着物联网技术的迅猛发展&#xff0c;人们深刻认识到在智能化生产和生活中&#xff0c;实时、可靠、安全的数据传输至关重要。在此背景下&#xff0c;高性能的物联网数据传输解决方案——协议转换网关应运而生&#xff0c;广泛应用于工业自动化和数字化工厂应用环境中。 无缝衔…...

explain工具优化mysql需要达到什么级别?

explain工具优化mysql需要达到什么级别&#xff1f; 一、explain工具是什么&#xff1f;二、explain查询后各字段的含义三、explain查询后type字段有哪些类型&#xff1f;四、type类型需要优化到哪个阶段&#xff1f; 一、explain工具是什么&#xff1f; explain是什么&#x…...

RHCE作业

架设一台NFS服务器&#xff0c;并按照以下要求配置 1、开放/nfs/shared目录&#xff0c;供所有用户查询资料 2、开放/nfs/upload目录&#xff0c;为192.168.xxx.0/24网段主机可以上传目录&#xff0c;并将所有用户及所属的组映射为nfs-upload,其UID和GID均为210 3、将/home/to…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

手游刚开服就被攻击怎么办?如何防御DDoS?

开服初期是手游最脆弱的阶段&#xff0c;极易成为DDoS攻击的目标。一旦遭遇攻击&#xff0c;可能导致服务器瘫痪、玩家流失&#xff0c;甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案&#xff0c;帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...

边缘计算医疗风险自查APP开发方案

核心目标:在便携设备(智能手表/家用检测仪)部署轻量化疾病预测模型,实现低延迟、隐私安全的实时健康风险评估。 一、技术架构设计 #mermaid-svg-iuNaeeLK2YoFKfao {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg…...

Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例

使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件&#xff0c;常用于在两个集合之间进行数据转移&#xff0c;如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model&#xff1a;绑定右侧列表的值&…...

MMaDA: Multimodal Large Diffusion Language Models

CODE &#xff1a; https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA&#xff0c;它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构&#xf…...

从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)

设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile&#xff0c;新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...

MySQL 8.0 OCP 英文题库解析(十三)

Oracle 为庆祝 MySQL 30 周年&#xff0c;截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始&#xff0c;将英文题库免费公布出来&#xff0c;并进行解析&#xff0c;帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...

在web-view 加载的本地及远程HTML中调用uniapp的API及网页和vue页面是如何通讯的?

uni-app 中 Web-view 与 Vue 页面的通讯机制详解 一、Web-view 简介 Web-view 是 uni-app 提供的一个重要组件&#xff0c;用于在原生应用中加载 HTML 页面&#xff1a; 支持加载本地 HTML 文件支持加载远程 HTML 页面实现 Web 与原生的双向通讯可用于嵌入第三方网页或 H5 应…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

SiFli 52把Imagie图片,Font字体资源放在指定位置,编译成指定img.bin和font.bin的问题

分区配置 (ptab.json) img 属性介绍&#xff1a; img 属性指定分区存放的 image 名称&#xff0c;指定的 image 名称必须是当前工程生成的 binary 。 如果 binary 有多个文件&#xff0c;则以 proj_name:binary_name 格式指定文件名&#xff0c; proj_name 为工程 名&…...