成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

分布式進階-鏈路追蹤SpringCloudSleuth、Zipkin【實戰篇】

開發 架構
Spring Cloud Sleuth 是 Spring Cloud 生態系統的一部分,它是一個分布式追蹤解決方案,用于監視微服務架構中的請求流程,并幫助開發者跟蹤請求在不同微服務之間的傳播路徑。

一、前言

我們在使用微服務的時候,往往涉及到各個微服務之間的調用,肯定會存在深度的調用鏈路,如果出現BUG或者異常,就會讓問題定位和處理效率非常低。有了Sleuth ,就可以幫助我們記錄、跟蹤應用程序中的請求和操作。通常與 Zipkin 配合使用,從而提供更全面的可視化應用程序跟蹤和分析功能。

就像ElasticSearch和Kibana一樣!

復雜的鏈路調用如下圖所示:

在繼續往下看的同時,需要你具備Springboot整合Nacos構建一個聚合項目的能力。

當然如果不想自己來,小編也給大家準備好了。大家可以下載運行一下,開始下面的實戰!

防止Github訪問不了,這里把代碼提交到了Gitee。

cloud-sleuth-zipkin-demo代碼下載地址:https://gitee.com/wang-zhenjun/cloud-sleuth-zipkin-demo

二、Spring Cloud Sleuth 介紹

1、簡介

Spring Cloud Sleuth 是 Spring Cloud 生態系統的一部分,它是一個分布式追蹤解決方案,用于監視微服務架構中的請求流程,并幫助開發者跟蹤請求在不同微服務之間的傳播路徑。

Sleuth主要用于解決微服務架構中的分布式系統跟蹤和調試問題。

官網文檔:https://docs.spring.io/spring-cloud-sleuth/docs/2.2.8.RELEASE/reference/html/。

2、核心概念

我們可以看一下官網的圖片:

簡單名詞介紹:

?

cs:「客戶端發送」,客戶已提出請求。該注釋指示跨度的開始。sr:「服務器已接收」,服務器端收到請求并開始處理。從此時間戳中減去cs時間戳即可得出網絡延遲。ss:「服務器發送」,在請求處理完成時(當響應發送回客戶端時)進行注釋。從這個時間戳中減去sr時間戳就可以得出服務器端處理請求所需的時間。cr:「客戶端已收到」,表示跨度的結束。客戶端已成功收到服務器端的響應。從此時間戳中減去cs時間戳即可得出客戶端從服務器接收響應所需的整個時間。

?

詳細信息可以看官網介紹,總結一下:

名詞

翻譯

解釋

Trace

追蹤

Trace 是一個請求的整體追蹤。它代表了從請求的起始點到結束點的完整路徑,經過多個微服務。每個 Trace 都有一個唯一的 Trace ID。

Span

跨度

Span 是 Trace 中的一個小段,它代表了請求在某個特定微服務上的處理過程。Spans 之間有父子關系,它們可以形成一個層次結構,以表示請求的處理路徑。

Trace ID

追蹤標識

Trace ID 是唯一標識一個 Trace 的標識符。它在整個 Trace 中保持不變,用于將不同的 Span 關聯到同一個 Trace 上。

Span ID

跨度標識

Span ID 是唯一標識一個 Span 的標識符。它用于在不同 Span 之間建立父子關系。

Parent Span ID

父 Span 標識

父 Span ID 是標識一個 Span 的父 Span 的標識符。它用于建立 Span 之間的關系。

Annotations

注解

Annotations 是關于 Span 的額外信息,通常用于記錄 Span 的開始和結束時間、操作名稱、以及其他相關信息。Annotations 可以幫助你更好地理解請求的處理過程。

Binary Annotations

二進制注解

Binary Annotations 是鍵值對形式的信息,用于記錄與 Span 相關的自定義信息,例如請求的狀態、錯誤信息等。

Collector

收集器

Collector 是用于收集追蹤信息的組件,它將追蹤數據發送到后端存儲或可視化工具(如Zipkin或Jaeger)。Collector 可以將 Span 數據持久化,以供分析和監視使用。

Sampler

采樣器

Sampler 用于確定是否對一個請求進行追蹤。它決定是否為請求創建一個 Trace。Sampler 可以根據策略決定是否記錄某個請求的 Trace 數據,以避免記錄過多的追蹤信息,從而降低性能開銷。

「官網的圖,每一個代表一個組件,他們之間進行調用,畫的少了Trace Id,加上就好了。」

每個組件都會生成一個 Trace Id(全局唯一),還會有 Span Id、Parent Id 三部分組成。鏈路上的所有組件組成一個完整的 Trace。

「注意:」

「頭鏈路Parent Id = null,其余的都指向上一個組件的Span Id,從而形成鏈路。」

「一次鏈路調用所有的組件Trace Id都是一樣的。」

「這里說的組件就是一個個的微服務!」

三、 Zipkin介紹和搭建

1、定義

Zipkin 是一個分布式追蹤系統。它有助于收集解決服務架構中的延遲問題所需的計時數據。功能包括該數據的收集和查找。

Zipkin官網地址:https://zipkin.io/。

2、核心概念

名詞

翻譯

解釋

Trace

追蹤

Trace 代表整個請求的追蹤路徑,跨越不同的服務。

Span

跨度

Span 是基本工作單位,代表了請求在單個服務中的處理過程。

Trace ID

追蹤標識

Trace ID 是唯一標識一個 Trace 的標識符,用于將不同的 Span 關聯到同一個 Trace 上。

Annotations

注解

Annotations 用于記錄 Span 的關鍵事件,通常包括開始和結束時間、操作名稱等。

Binary Annotations

二進制注解

Binary Annotations 用于記錄額外的自定義信息,例如請求狀態、錯誤信息等。

Collector

收集器

Collector 負責接收和存儲從不同服務發送的 Span 數據,以便后續的檢查和分析。

Query and Visualization

查詢和可視化

提供了查詢和可視化界面,允許用戶查看和分析跟蹤數據,以幫助故障排查和性能優化。

盡管Sleuth 和 Zipkin有些術語和概念中有相似之處,但它們是兩個不同的工具,各自有自己的實現和用途。

「Spring Cloud Sleuth 用于生成和傳播跟蹤信息,而 Zipkin 用于收集、存儲、查詢和可視化這些信息。它們可以協同工作,但也可以獨立使用。」

3、docker搭建

官方有三種方式搭建,推薦使用:「如果您熟悉 Docker,這是首選的啟動方法。」

Docker Zipkin項目能夠構建 docker 鏡像、提供腳本和docker-compose.yml 用于啟動預構建鏡像的腳本。

https://github.com/openzipkin/docker-zipkin/blob/master/docker-compose.yml。

最快的啟動方式是直接運行最新的鏡像:

docker run -d -p 9411:9411 openzipkin/zipkin

我們啟動成功,在Windows下訪問看是否成功!

http://192.168.239.130:9411/zipkin/

「注意:」

「Zipkin默認將追蹤數據信息保存到內存,重啟服務后追蹤數據丟失,Zipkin支持將追蹤數據持久化到MySQL或ES。」

可以直接使用docker-componse運行:

docker-componse運行腳本:https://github.com/openzipkin/zipkin/tree/master/docker/examples

可以自行試一下,這里就不帶大家演示了!

四、Springboot整合

今天我們來進行簡單的鏈路模擬:

「service-order模塊調用service-stock模塊調用service-message模塊」

「通信我們使用openFeign來進行調用,三個模塊統一使用nacos進行注冊」

大家可以下載一下項目體驗一下,可以自己搭建,就是一個聚合項目!

結構如下:

1、導入依賴

這是父依賴。

<properties>
    <spring.boot.version>2.7.3</spring.boot.version>
    <spring.cloud.dependencies.version>2021.0.1</spring.cloud.dependencies.version>
    <spring.cloud.alibaba.version>2021.0.1.0</spring.cloud.alibaba.version>
    <java.version>1.8</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <org.projectlombok.lombok>1.18.26</org.projectlombok.lombok>
</properties>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring.cloud.dependencies.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${spring.boot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-alibaba-dependencies</artifactId>
            <version>${spring.cloud.alibaba.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>${org.projectlombok.lombok}</version>
        </dependency>
    </dependencies>
</dependencyManagement>

spring-cloud-dependencies里包含了sleuth、zipkin的依賴,父不需要再定義管理版本。

子依賴要比父依賴多了sleuth、zipkin兩個,還有openFeign的包!

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

<!--Zipkin 依賴-->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-sleuth-zipkin</artifactId>
</dependency>

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

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

2、yml配置

三份自己改一下端口和應用名稱:service-order、service-stock、service-message;端口分別為:9000、9001、9002

server:
  port: 9000

spring:
  application:
    # 應用名稱
    name: service-order
  cloud:
    nacos:
      discovery:
        # 服務注冊地址
        server-addr: localhost:8848
  zipkin:
    base-url: http://192.168.239.130:9411
    sender:
      type: web # 設置使用 http 的方式傳輸數據

3、詳細代碼

記得在啟動類上添加注解:@EnableFeignClients,表示開啟feign調用。

完整的結構如下:

下面把具體代碼給大家:OrderController :

/**
 * @author wangzhenjun
 * @date 2023/10/31 14:25
 */
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/order")
@RestController
public class OrderController {

    private final RemoteStockFeignService remoteStockFeignService;
    /**
     * 模擬下單流程
     * @param userId
     * @param productId
     * @return
     */
    @GetMapping("/createOrder")
    public String createOrder(@RequestParam("userId") Integer userId, @RequestParam("productId") Integer productId) {
        log.info("====>訂單模塊<========");
        // 調用庫存服務進行庫存扣減
        String stockResult = remoteStockFeignService.subtractStock(userId,productId,1);
        log.info("扣減庫存結果:{}", stockResult);
        // 還有其他。。。。。

        return "下單成功!";
    }
}

RemoteStockFeignService :

/**
 * @author wangzhenjun
 * @date 2023/10/31 14:29
 */
@FeignClient(value = "service-stock")
public interface RemoteStockFeignService {

    @GetMapping(value = "/stock/subtractStock")
    String subtractStock(@RequestParam(value = "userId") Integer userId,@RequestParam(value = "productId") Integer productId,@RequestParam(value = "num") Integer num);
}

StockController :

/**
 * @author wangzhenjun
 * @date 2023/10/31 14:40
 */
@Slf4j
@RequiredArgsConstructor
@RequestMapping("/stock")
@RestController
public class StockController {

    private final RemoteMessageFeignService remoteMessageFeignService;

    @GetMapping(value = "/subtractStock")
    public String subtractStock(@RequestParam(value = "userId") Integer userId,@RequestParam(value = "productId") Integer productId, @RequestParam(value = "num") Integer num) {
        log.info("====>庫存模塊<========");
        if (productId < 1) {
            throw new RuntimeException("商品不存在,請重新請求!");
        }
        // 調用短信模塊給用戶發下單成功短信
        String messageResult = remoteMessageFeignService.sendMessage(userId);
        log.info("發送短信結果:{}", messageResult);
        return "扣減庫存成功!";
    }
}

RemoteMessageFeignService:

/**
 * @author wangzhenjun
 * @date 2023/10/31 14:29
 */
@FeignClient(value = "service-message")
public interface RemoteMessageFeignService {

    @GetMapping(value = "/message/sendMessage/{userId}")
    String sendMessage(@PathVariable(value = "userId") Integer userId);
}

MessageController :

/**
 * @author wangzhenjun
 * @date 2023/10/31 14:40
 */
@Slf4j
@RequestMapping("/message")
@RestController
public class MessageController {


    @GetMapping(value = "/sendMessage/{userId}")
    public String sendMessage(@PathVariable(value = "userId") Integer userId) {
        log.info("====>短信模塊<========");
        if (userId < 1 || userId > 999999) {
            throw new RuntimeException("用戶不存在,請重新請求!");
        }
        return "發送短信成功!";
    }
}

4、啟動nacos

Windows下啟動nacos,找到nacos下的bin目錄執行命令:

startup.cmd -m standalone

找到地址,訪問。用戶名密碼都是nacos。可以在配置文件中修改!

5、注冊成功

我們把三個模塊進行啟動!nacos上已經可以看到我們的服務注冊上了,可以通過服務名進行調用了!

五、調試

我們以訂單模塊為入口進行鏈路調用:

http://localhost:9000/order/createOrder?userId=2&productId=89。

1、查看日志

我們看一下訂單模塊的日志。

可以總結出Sleuth 日志格式:

[service-order,e36ebe859a7473e7,e36ebe859a7473e7]

[服務名稱,Trace ID,Span ID]

在最開始的鏈路上,Trace ID 和 Span ID 的值通常是相同的,這是因為它們都代表了整個請求的追蹤。

「一條鏈路使用一個相同的Trace ID。」

在日志沒有體現出Parent Span ID,不過不應該,我們可以通過Zipkin來看鏈路!

2、Zipkin查看

前面我們已經進入了Zipkin頁面了,只需要刷新一下就可以看到每次鏈路的記錄了!

點擊SHOW按鈕,可以看到詳細鏈路信息:

耗時,深度,Trance ID 還是挺好的。

3、模擬異常

我們來把商品修改一下:

http://localhost:9000/order/createOrder?userId=2&productId=-89。

此時是庫存服務出現的問題,就不會展示下一個消息模塊,自然而然的找到了出現問題的鏈路和根源!

在模擬一個三級錯誤的,就會看到鏈路的最后一級!

下面還可以查詢依賴關系:

點擊節點,可以查看匯總,調用次數和失敗次數的統計分析!

六、總結

分布式鏈路追蹤已經成為現代微服務架構中不可或缺的工具之一。

通過它,我們可以清晰地跟蹤請求的調用路徑,了解系統的性能,診斷潛在問題,并不斷優化我們的應用程序。

Spring Cloud Sleuth讓我們輕松生成和傳播跟蹤信息,使我們的微服務能夠協同工作,無縫地捕捉每個請求的處理路徑。

Zipkin作為一個流行的分布式追蹤系統,為我們提供了可視化界面,使我們能夠以圖形化的方式查看和分析跟蹤數據。

「當然簡單系統上這個大材小用,但是我們可以在項目中試試,加了也不會影響程序的正常運行,做一個簡單的知識儲備!」

責任編輯:姜華 來源: 小王博客基地
相關推薦

2020-12-16 09:24:18

Skywalking分布式鏈路追蹤

2024-06-07 13:04:31

2024-08-21 08:09:17

2024-01-26 07:49:49

Go分布式鏈路

2022-05-25 08:23:32

ZipKinTwitter開源項目

2021-02-22 07:58:51

分布式鏈路追蹤

2020-09-11 09:44:04

微服務分布式鏈路

2024-07-09 08:11:56

2024-11-28 08:57:21

分布式鏈路Skywalking

2021-11-08 14:10:37

分布式Spring鏈路

2022-11-26 09:49:07

分布式鏈路追蹤技術

2022-08-05 10:03:17

分布式微服務

2022-05-23 08:23:24

鏈路追蹤SleuthSpring

2023-10-26 00:00:00

分布式系統定位

2024-10-24 08:51:19

分布式鏈路項目

2020-05-26 11:59:30

日志鏈路微服務架構

2011-09-13 14:21:00

IRF交換機基礎分布式鏈路聚合

2022-02-18 09:30:48

分布式Spring應用程序

2025-03-11 14:16:09

2022-09-25 22:19:24

Dapr分布式追蹤
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久99国产精品 | 国产精品视屏 | 久久人人爽人人爽人人片av免费 | 国产午夜精品一区二区三区嫩草 | 亚洲国产成人精品女人 | 天天操天天干天天透 | 亚洲成人黄色 | 色综合久久久 | 国产片侵犯亲女视频播放 | 99精品亚洲国产精品久久不卡 | 91最新视频 | 国产激情在线 | 欧美一区两区 | 亚洲成人一区二区在线 | 一区二区三区欧美 | av国产在线观看 | 国产日产精品一区二区三区四区 | 激情五月综合网 | 欧美日韩在线不卡 | 欧美一二三| 亚洲狠狠 | 91精品国产综合久久婷婷香蕉 | 亚洲国产一区二区视频 | 亚洲一区二区三区免费观看 | 成人免费网站 | 国产一区二区三区久久久久久久久 | 国产精品视频一区二区三区 | 久久久久久久久久久久久9999 | 久久99精品久久久久久青青日本 | 国产精品视频一区二区三区 | 亚洲精品乱码久久久久久按摩观 | 一区二区三区欧美 | 日韩在线小视频 | 中文字幕在线精品 | 国产精品久久午夜夜伦鲁鲁 | 日韩av一二三区 | 在线国产视频 | 91久久看片 | 国产美女福利在线观看 | 欧美一区视频 | 国产精品久久久久久久久久久久 |