【微服务】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 {

    @Autowired
    private 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 {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Override
    public 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 {

    @Autowired
    private 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 {

    @Autowired
    private  UserFeignService userFeignService;

    @Override
    public 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: 9002

spring:
  application:
    name: user-service

  zipkin:
    base-url: http://127.0.0.1:9411
  sleuth:
    sampler:
      probability: 1

  cloud:
    nacos:
      discovery:
        server-addr: nacos地址:8848

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

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

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

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

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

七、写在文末

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

linux 使用笔记

1.查看运行内存 a.Free 快速查看内存的方法&#xff0c;也是经常使用的命令&#xff0c; -h 更人性化的显示内存的单元 -m 以M的形式显示 b.Top Top命令提供了实时性的运行中的程序的资源使用统计。可以根据内存的使用和大小来进行排序。 如上所示&#xff0c;top命令可以看…

Servlet系列两种创建方式

一、使用web.xml的方式配置&#xff08;Servlet2.5之前使用&#xff09; 在早期版本的Java EE中&#xff0c;可以使用XML配置文件来定义Servlet。在web.xml文件中&#xff0c;可以定义Servlet的名称、类名、初始化参数等。然后&#xff0c;在Java代码中实现Servlet接口&#x…

C++逆向分析New_Delete

一个运行程序是一定有四个区域&#xff0c;分别是&#xff1a;代码区&#xff0c;数据区&#xff0c;栈区&#xff0c;堆区。 栈区我们知道&#xff0c;是函数传参保存临时变量的一段内存空间。那么堆区是干嘛的呢&#xff1f; 堆区就是动态开辟的一块内存空间&#xff0c;用…

年味渐近 其乐龍龍!2024四川省网联会年货节闪亮来袭!

1月19日&#xff0c;“其乐龍龍2024四川省网联会年货节”正式启动&#xff0c;此次活动由四川省网联会主办&#xff0c;以直播、短视频多种形式在抖音、微博、小红书等多平台同步呈现&#xff0c;旨在为广大消费者带来一场别开生面的年货盛宴&#xff0c;助力激发消费活力。 年…

数据结构:链式队列

队列是限制在两端操作进行插入操作与删除操作的线性表&#xff0c;允许进行插入操作的一端称为"队尾"&#xff0c;允许进行删除操作的一端称为“队头”。当线性表中没有元素时&#xff0c;称为“空队”。队列的特点是先进先出。 队列两种规定&#xff1a; 1、front…

2024年网络安全比赛--内存取证(超详细)

一、竞赛时间 180分钟 共计3小时 二、竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 1.从内存文件中找到异常程序的进程,将进程的名称作为Flag值提交; 2.从内存文件中找到黑客将异常程序迁移后的进程编号,将迁移后的进程编号作为Flag值提交; 3.从内存文件中找到受害者…

计算机体系结构——多处理机系统

一、概述 重要概念 评估指标 通信延迟 通信延迟&#xff1d;发送开销&#xff0b;跨越时间&#xff0b;传输延迟&#xff0b;接收开销 跨越时间 数字信号从发送方的线路端传送到接收方的线路端所经过的时间。 传输时间 全部的消息量除以线路带宽。 多处理机的架构 根…

考研数学:幂函数凑微分的三道典型例题

题目 01 题目 02 题目 03 详细内容和更多题目解析在&#xff1a;荒原之梦考研数学

Python Timer定时器:控制函数在特定时间执行

Thread类有一个Timer子类&#xff0c;该子类可用于控制指定函数在特定时间内执行一次。例如如下程序&#xff1a; from threading import Timerdef hello():print("hello, world") # 指定10秒后执行hello函数 t Timer(10.0, hello) t.start() 上面程序使用 Timer …

Pandas.DataFrame.mean() 平均值 详解 含代码 含测试数据集 随Pandas版本持续更新

关于Pandas版本&#xff1a; 本文基于 pandas2.1.2 编写。 关于本文内容更新&#xff1a; 随着pandas的stable版本更迭&#xff0c;本文持续更新&#xff0c;不断完善补充。 Pandas稳定版更新及变动内容整合专题&#xff1a; Pandas稳定版更新及变动迭持续更新。 Pandas API参…

初始RabbitMQ(入门篇)

消息队列(MQ) 本质上就是一个队列,一个先进先出的队列,队列中存放的内容是message(消息),是一种跨进程的通信机制,用于上下游传递消息, 为什么使用MQ: 削峰填谷: MQ可以很好的做一个缓冲机制,例如在一个系统中有A和B两个应用,A是接收用户的请求的,然后A调用B进行处理. 这时…

C++ STL之string的使用及模拟实现

文章目录 1. 前言2. 介绍3. string类的使用3.1 string类的构造函数3.2 string类对象的容量操作3.3 string类对象的访问及遍历操作3.4 string类对象的修改操作3.5 string类对象的字符串操作3.6 string类的非成员函数 4. string类的模拟实现 1. 前言 C语言中&#xff0c;字符串是…

如何在 Ubuntu / Raspbian 上安装 MariaDB

Raspberry Pi OS&#xff08;原为Raspbian&#xff09;是为树莓派基于Debian开发的操作系统。 从2015年起&#xff0c;树莓派基金会正式将其作为树莓派的官方操作系统。 Raspbian是由Mike Thompson和Peter Green创建的一个独立项目。第一个版本于2012年6月发布&#xff0c;至…

php基础学习之变量

php使用变量的必要性 PHP 是一种动态网站开发的脚本语言&#xff0c;动态语言特点是交互性&#xff0c;会有数据的传递&#xff0c;而 PHP作为“中间人”&#xff0c;需要进行数据的传递&#xff0c;传递的前提就是 PHP 能自己存储数据(临时存储) php变量的命名规则 必须以do…

Android Studio 之 菜单 Menu

选项菜单 OptionsMenu 用xml添加&#xff08;更建议使用&#xff09; 创建一个菜单布局 : 在 res文件下新建一个menu 目录&#xff0c;此时的菜单id为&#xff1a;R.menu.option <?xml version"1.0" encoding"utf-8"?> <menu xmlns:android&…

从一到无穷大 #21 从基于多数据模型分析负载的Benchmark讨论多模数据库的发展方向

本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。 本作品 (李兆龙 博文, 由 李兆龙 创作)&#xff0c;由 李兆龙 确认&#xff0c;转载请注明版权。 文章目录 引言M2Bench测试结果从Lindorm看待多模的发展方向总结 引言 《M2Bench: A Database …

Java 面向对象 03 就近原则和this关键字

对于起名字需要见名知意&#xff0c;所以这个String n 不太合适&#xff1a; 但是如果将n改为name&#xff0c;会与第五行代码的name重复&#xff1a; 运行代码发现&#xff0c;获取后的姓名为默认值&#xff0c;是null 引入就近原则&#xff1a; 此处打印的是age10&#xff0c…

CPU相关专业名词介绍

CPU相关专业名词 1、CPU 中央处理器CPU&#xff08;Central Processing Unit&#xff09;是计算机的运算和控制核心&#xff0c;可以理解为PC及服务器的大脑CPU与内部存储器和输入/输出设备合称为电子计算机三大核心部件CPU的本质是一块超大规模的集成电路&#xff0c;主要功…

2024.1.21周报

目录 摘要 ABSTRACT 一、文献阅读 一、题目 二、摘要 三、Introduction 四、模型 一、连续时间模型 二、离散时间模型 五、结论 二、实验代码 Navier–Stokes equation 总结 摘要 本周我阅读了一篇题目为Physics-informed neural networks: A deep learning fra…

IDEA2023.2 将普通项目转Maven项目

1、选中一个普通工程&#xff1a; 2、快捷键&#xff1a;ctrlshift a&#xff0c;搜索&#xff1a;Add Framework Support… 3、勾选maven&#xff0c;点击ok。