锋盈数科-知识库 Logo
首页
软件开发
计算机基础
Hello Halo
新手必读
关于本知识库
登录 →
锋盈数科-知识库 Logo
首页 软件开发 计算机基础 Hello Halo 新手必读 关于本知识库
登录
  1. 首页
  2. 软件开发
  3. Spring Cloud-08-微服务监控之分布式链路追踪技术 Sleuth + Zipkin

Spring Cloud-08-微服务监控之分布式链路追踪技术 Sleuth + Zipkin

0
  • 软件开发
  • 发布于 2024-08-19
  • 0 次阅读
黄健
黄健

分布式链路追踪技术适用场景(问题场景)

场景描述

  为了⽀撑⽇益增⻓的庞大业务量,我们会使⽤微服务架构设计我们的系统,使得我们的系统不仅能够通过集群部署抵挡流量的冲击,⼜能根据业务进⾏灵活的扩展。
那么,在微服务架构下,⼀次请求少则经过三四次服务调⽤完成,多则跨越⼏⼗个甚⾄是上百个服务节点。那么问题接踵⽽来:

  1. 如何动态展示服务的调⽤链路?(⽐如A服务调⽤了哪些其他的服务---依赖关系)

  2. 如何分析服务调⽤链路中的瓶颈节点并对其进⾏调优?(⽐如A--->B--->C,C服务处理时间特别⻓)

  3. 如何快速进⾏服务链路的故障发现?这就是分布式链路追踪技术存在的⽬的和意义

分布式链路追踪技术

  如果我们在⼀个请求的调⽤处理过程中,在各个链路节点都能够记录下⽇志,并最终将⽇志进⾏集中可视化展示,那么我们想监控调⽤链路中的⼀些指标就有希望了~~~⽐如,请求到达哪个服务实例?请求被处理的状态怎样?处理耗时怎样?这些都能够分析出来了...

  分布式环境下基于这种想法实现的监控技术就是就是分布式链路追踪(全链路追踪)

市场上的分布式链路追踪⽅案

分布式链路追踪技术已然成熟,产品也不少,国内外都有,比如

  • Spring Cloud Sleuth + Twitter Zipkin
  • 阿⾥巴巴的"鹰眼"
  • ⼤众点评的"CAT"
  • 美团的"Mtrace"
  • 京东的"Hydra"
  • 新浪的"Watchman"
  • 另外还有最近也被提到很多的Apache Skywalking。

分布式链路追踪技术核心思想

本质:记录⽇志,作为⼀个完整的技术,分布式链路追踪也有⾃⼰的理论和概念

微服务架构中,针对请求处理的调⽤链可以展现为⼀棵树,示意如下:


上图描述了⼀个常⻅的调⽤场景,⼀个请求通过⽹关服务路由到下游的微服务-1,然后微服务-1调⽤微服务-2,拿到结果后再调⽤微服务-3,最后组合微服务-2和微服务-3的结果,通过⽹关返回给用户

  为了追踪整个调⽤链路,肯定需要记录⽇志,⽇志记录是基础,在此之上肯定有⼀些理论概念,当下主流的的分布式链路追踪技术/系统所基于的理念都来⾃于Google的⼀篇论⽂《Dapper, a Large-Scale Distributed Systems TracingInfrastructure》,这⾥⾯涉及到的核⼼理念是什么,我们来看下,还以前⾯的服务调⽤来说


上图标识⼀个请求链路,⼀条链路通过TraceId唯⼀标识,span标识发起的请求信息,各span通过parrentId关联起来

Trace: 服务追踪的追踪单元是从客户发起请求(request)抵达被追踪系统的边界开始,到被追踪系统向客户返回响应(response)为⽌的过程

Trace ID: 为了实现请求跟踪,当请求发送到分布式系统的⼊⼝端点时,只需要服务跟踪框架为该请求创建⼀个唯⼀的跟踪标识Trace ID,同时在分布式系统内部流转的时候,框架失踪保持该唯⼀标识,直到返回给请求⽅

  ⼀个Trace由⼀个或者多个Span组成,每⼀个Span都有⼀个SpanId,Span中会记录TraceId,同时还有⼀个叫做ParentId,指向了另外⼀个Span的SpanId,表明⽗⼦关系,其实本质表达了依赖关系

Span ID: 为了统计各处理单元的时间延迟,当请求到达各个服务组件时,也是通过⼀个唯⼀标识Span ID来标记它的开始,具体过程以及结束。对每⼀个Span来说,它必须有开始和结束两个节点,通过记录开始Span和结束Span的时间戳,就能统计出该Span的时间延迟,除了时间戳记录之外,它还可以包含⼀些其他元数据,⽐如时间名称、请求信息等。


每⼀个Span都会有⼀个唯⼀跟踪标识 Span ID,若⼲个有序的 span 就组成了⼀个trace。

  Span可以认为是⼀个⽇志数据结构,在⼀些特殊的时机点会记录了⼀些⽇志信息,⽐如有时间戳、spanId、TraceId,parentIde等,Span中也抽象出了另外⼀个概念,叫做事件,核⼼事件如下

  • CS :client send/start 客户端/消费者发出⼀个请求,描述的是⼀个span开始

  • SR: server received/start 服务端/⽣产者接收请求 SR-CS属于请求发送的⽹络延迟

  • SS: server send/finish 服务端/⽣产者发送应答 SS-SR属于服务端消耗时间

  • CR:client received/finished 客户端/消费者接收应答 CR-SS表示回复需要的时间(响应的⽹络延迟)

  Spring Cloud Sleuth (追踪服务框架)可以追踪服务之间的调⽤,Sleuth可以记录⼀个服务请求经过哪些服务、服务处理时⻓等,根据这些,我们能够理清各微服务间的调⽤关系及进⾏问题追踪分析。

  • 耗时分析:通过 Sleuth 了解采样请求的耗时,分析服务性能问题(哪些服务调⽤⽐较耗时)

  • 链路优化:发现频繁调⽤的服务,针对性优化等Sleuth就是通过记录⽇志的⽅式来记录踪迹数据的

注意: 我们往往把Spring Cloud Sleuth 和 Zipkin ⼀起使⽤,把 Sleuth 的数据信息发送给 Zipkin 进⾏聚合,利⽤ Zipkin 存储并展示数据。

Sleuth + Zipkin

基于之前文章中使用的工程,新增链路追踪功能

  1. 每⼀个需要被追踪踪迹的微服务⼯程都引⼊依赖坐标
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-sleuth</artifactId>
        </dependency>
  1. 每⼀个微服务都修改application.yml配置⽂件,添加⽇志级别
logging:
  level:
    org.springframework.web.servlet.DispatcherServlet: debug
    org.springframework.cloud.sleuth: debug

请求到来时,我们在控制台可以观察到 Sleuth 输出的⽇志(全局 TraceId、SpanId等)。

结合 Zipkin 展示追踪数据

Zipkin 包括Zipkin Server和 Zipkin Client两部分,Zipkin Server是⼀个单独的服务,Zipkin Client就是具体的微服务

Zipkin Server 构建

SpringCloud从F版之后就不需要自己构建Zipkin Server了,只需要调用相关jar包即可,最新版本下载地址下载其jar包到本地,我下的是当前最新的zipkin-server-2.23.2-exec.jar进入到该jar包的目录,在命令行中输入java -jar命令运行该jar文件:

java -jar zipkin-server-2.23.2-exec.jar

如果上面的地址失效可以去github主页找到最新的下载链接github项目地址

启动后访问http://localhost:9411/

Zipkin Client 构建

  1. 在之前的三个微服务(gateway、autodeliver、resume)中添加依赖
        <!--包含了sleuth+zipkin-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zipkin</artifactId>
        </dependency>
  1. application.yml 中添加对zipkin server的引⽤
  zipkin:
    base-url: http://127.0.0.1:9411 # zipkin server的请求地址
    sender:
   # web 客户端将踪迹日志数据通过网络请求的方式传送到服务端,另外还有配置
   # kafka/rabbit 客户端将踪迹日志数据传递到mq进行中转
    type: web
  sleuth:
    sampler:
   # 采样率 1 代表100%全部采集 ,默认0.1 代表10% 的请求踪迹数据会被采集
   # 生产环境下,请求量非常大,没有必要所有请求的踪迹数据都采集分析,对于网络包括server端压力都是比较大的,可以配置采样率采集一定比例的请求的踪迹数据进行分析即可
      probability: 1

另外,对于log⽇志,依然保持开启debug状态

  1. 上述三个服务改动完后重启,在进行一次调用,在zikpin页面上面查看记录


Zipkin server ⻚⾯⽅便我们查看服务调⽤依赖关系及⼀些性能指标和异常信息

追踪数据Zipkin持久化到mysql

  1. mysql中创建名称为zipkin的数据库,并执⾏如下sql语句(官⽅提供)
    源码路径如下zipkin-2.23.2\zipkin-storage\mysql-v1\src\main\resources\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 database zipkin;

use 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.23.2-exec.jar --STORAGE_TYPE=mysql --MYSQL_HOST=192.168.137.144 --MYSQL_TCP_PORT=3306 --MYSQL_DB=zipkin --MYSQL_USER=root --MYSQL_PASS=123456

原文链接: https://blog.csdn.net/Kiven_ch/article/details/118342881

标签: #SpringCloud 49 #软件开发 1171 #JAVA 991
相关文章

万字:支付“核心系统”详解 2024-11-02 15:33

专栏作者:隐墨星辰 \| 主编:陈天宇宙 这篇文章也尝试化繁为简,探寻支付系统的本质,讲清楚在线支付系统最核心的一些概念和设计理念。 虽然支付行业已经过了风头最劲的时光,但跨境支付仍然在蓬勃发展,每年依然有很多新人进入这个行业,这篇文章尝试为这些刚入行的新人提供一点帮助。 文章只介绍一些支付行业十几

资深支付架构师视角:实战从问题定义到代码落地的完整套路 2024-11-02 15:33

前言 今天从一个实际案例入手,介绍站在架构师的角度,如何识别并定义问题,提炼需求,技术方案选型,再到详细设计,最后利用AI的能力协助写出核心的代码,验证与调优。 解决问题存在一定的模式,也可以称之为框架,总结出自己的思考和解题框架,以后再碰到同类型的问题就可以如庖丁解牛一样容易。 很多年前,我写代码

Spring 实现 3 种异步接口 2024-10-18 09:07

大家好,我是苏三~ 如何处理比较耗时的接口? 这题我熟,直接上异步接口,使用 Callable、WebAsyncTask 和 DeferredResult、CompletableFuture等均可实现。 但这些方法有局限性,处理结果仅返回单个值。在某些场景下,如果需要接口异步处理的同时,还持续不断地

重学SpringBoot3-集成Redis(五)之布隆过滤器 2024-10-08 11:24

更多SpringBoot3内容请关注我的专栏:《SpringBoot3》 期待您的点赞👍收藏⭐评论✍ 重学SpringBoot3-集成Redis(五)之布隆过滤器 1. 什么是布隆过滤器? * 基本概念 适用场景 2. 使用 Redis 实现布隆过滤器 * 项目依赖 Redis 配置

设计模式第16讲——迭代器模式(Iterator) 2024-10-08 11:24

一、什么是迭代器模式 迭代器模式是一种行为型设计模式,它提供了一种统一的方式来访问集合对象中的元素,而不是暴露集合内部的表示方式。简单地说,就是将遍历集合的责任封装到一个单独的对象中,我们可以按照特定的方式访问集合中的元素。 二、角色组成 抽象迭代器(Iterator):定义了遍历聚合对象所需的方法

vue2路由和vue3路由区别及原理 2024-10-08 11:24

一、Vue2 与 Vue3 路由的区别 1. 创建路由实例方式的不同 Vue 2 中,通过 Vue.use() 注册路由插件,并通过 new VueRouter() 来创建路由实例。 import Vue from 'vue';import VueRouter from 'vue-router';i

目录

IT 外包服务商

  • 意见投递
  • zyf6619

软件开发应用

主菜单

  • 首页
  • 软件开发
  • 计算机基础
  • Hello Halo
  • 新手必读
  • 关于本知识库
Copyright © 2024 your company All Rights Reserved. Powered by Halo.