主頁 > 後端開發 > 學習一下 SpringCloud (五)-- 配置中心 Config、訊息總線 Bus、鏈路追蹤 Sleuth、配置中心 Nacos

學習一下 SpringCloud (五)-- 配置中心 Config、訊息總線 Bus、鏈路追蹤 Sleuth、配置中心 Nacos

2021-02-26 06:13:38 後端開發

(1) 相關博文地址:

學習一下 SpringCloud (一)-- 從單體架構到微服務架構、代碼拆分(maven 聚合): https://www.cnblogs.com/l-y-h/p/14105682.html
學習一下 SpringCloud (二)-- 服務注冊中心 Eureka、Zookeeper、Consul、Nacos :https://www.cnblogs.com/l-y-h/p/14193443.html
學習一下 SpringCloud (三)-- 服務呼叫、負載均衡 Ribbon、OpenFeign : https://www.cnblogs.com/l-y-h/p/14238203.html
學習一下 SpringCloud (四)-- 服務降級、熔斷 Hystrix、Sentinel : https://www.cnblogs.com/l-y-h/p/14364167.html

 

(2)代碼地址:

https://github.com/lyh-man/SpringCloudDemo

 

一、引入配置中心

1、問題 與 解決

【問題:】
    通過前面幾篇博客介紹,完成了基本專案創建、服務注冊中心、服務呼叫、負載均衡、服務降級 以及 服務熔斷,    
    
    即 各個模塊 已經能正常通信、共同對外提供服務了,且有了一定的容錯能力,
    
    對于一個復雜的分布式系統來說,可能存在數十個模塊,每個模塊都有不同的配置資訊,
    
    而這就帶來了一個問題 -- 如何修改配置資訊?
    
【如何修改配置資訊:】

    一般修改配置資訊后,都得重新啟動一下服務以應用新的配置,
    
    在開發階段,頻繁修改配置資訊、啟動服務是很正常的,但是對于一個正在運行的系統,每次修改配置資訊,都得重新啟動一下服務,這期間的損失必然是很大的,
    
舉個例子: 
    游戲中的停服維護,你玩某個游戲玩得正嗨,結果接到通知需停服 3 天進行維護,那豈不很蛋疼,瞬間失去了玩游戲的興趣,
    
    對于一個復雜的分布式系統來說,可能存在數十個模塊,若一個模塊一個模塊的進行 修改、重啟服務,這將是一個非常繁瑣、且易出錯的作業,
    
    所以需要一款軟體,用來 集中式的管理 配置資訊、并實作動態修改配置資訊,
    
【解決:】
    集中式管理配置資訊、動態修改配置資訊,
注:
    集中式管理,類似于 Eureka 服務注冊中心進行理解,即可以在某個地方進行配置資訊的處理(可以查看到所有的微服務的配置資訊),
    動態修改,即不需要重啟微服務,修改后可以直接應用到正在運行的系統上,
    
相關技術:
    Config
    Nacos(推薦使用)

 

二、配置中心 -- Config

1、Config 是什么?

(1)Config 是什么?

【Config:】
    SpringCloud Config 為分布式系統提供了集中式的外部配置支持,
    分為 服務器端(Config Server) 以及 客戶端(Config Client),
Config Server:
    服務端也稱為 分布式配置中心,屬于一個獨立的 微服務應用,
    其用于連接配置服務器,并向客戶端提供配置資訊,
    即使用 Config Server 可以集中管理所有環境的配置資訊,其默認使用 Git 實作集中化管理的功能,
注:
    使用 Git 管理配置資訊,便于進行版本控制(可以使用 Git 客戶端工具進行操作),

Config Client:
    客戶端系結指定的服務端,從配置中心獲取配置資訊,

【官網地址:】
    https://spring.io/projects/spring-cloud-config
    https://docs.spring.io/spring-cloud-config/docs/current/reference/html/

 

 

 

 

 

(2)Config 功能

【功能:】
    集中式的管理組態檔,
    可以指定環境進行配置,比如:dev、test、prod、release 等,
    運行期間動態修改配置(在配置中心修改后,微服務從配置中心獲取配置資訊,微服務無需重啟),
    配置資訊以 Rest 介面的形式對外暴露,

 

2、搭建配置中心(Config Server)

(1)建立一個 Git 倉庫
  Config Server 默認使用 Git 實作集中化管理配置資訊,即 使用 Git 存盤配置資訊,
  所以需要建立一個 Git 倉庫,用于存盤配置資訊,
如下:
  進入 碼云 (或者 Github) 中,創建一個名為 SpringCloudConfig 的 Git 倉庫,
  倉庫地址為:https://gitee.com/lyh-man/spring-cloud-config.git

 

 

 

(2)新建一個子工程 config_server_9100,作為 Config Server
Step1:
  修改 父工程、當前工程 pom.xml 檔案,并引入相關依賴,
  此處以 Eureka 作為服務注冊中心,需要引入相關依賴,

【依賴:】
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

 

 

 

Step2:
  修改組態檔,

【application.yml】
server:
  port: 9100
spring:
  application:
    name: config_server
  cloud:
    config:
      # 獲取組態檔的分支,默認為 master
      label: master
      server:
        git:
          # git 倉庫地址
          uri: https://gitee.com/lyh-man/spring-cloud-config.git
          # 組態檔搜索路徑
          search-paths:
            - SpringCloudConfig

eureka:
  instance:
    appname: config_server # 優先級比 spring.application.name 高
    instance-id: ${eureka.instance.appname} # 設定當前實體 ID
  client:
    register-with-eureka: true # 默認為 true,注冊到 注冊中心
    fetch-registry: true # 默認為 true,從注冊中心 獲取 注冊資訊
    service-url:
      # 指向 注冊中心 地址,也即 eureka_server_7000 的地址,
      defaultZone: http://localhost:7000/eureka

 

 

 

Step3:
  在 config_server_9100 啟動類上添加 @EnableConfigServer 注解,

 

 

 

Step4:
  啟動 eureka_server_7000 以及 config_server_9100,
  新增一個檔案 config-dev.yml,并提交到 master 分支,內容如下:

【config-dev.yml:】
server:
  port: 9100
spring:
  application:
    name: config_server
  cloud:
    config:
      # 獲取組態檔的分支,默認為 master
      label: master
      server:
        git:
          # git 倉庫地址
          uri: https://gitee.com/lyh-man/spring-cloud-config.git
          # 組態檔搜索路徑
          search-paths:
            - SpringCloudConfig

eureka:
  instance:
    appname: config_server # 優先級比 spring.application.name 高
    instance-id: ${eureka.instance.appname} # 設定當前實體 ID
  client:
    register-with-eureka: true # 默認為 true,注冊到 注冊中心
    fetch-registry: true # 默認為 true,從注冊中心 獲取 注冊資訊
    service-url:
      # 指向 注冊中心 地址,也即 eureka_server_7000 的地址,
      defaultZone: http://localhost:7000/eureka

 

此時訪問:http://localhost:9100/master/config-dev.yml,即可獲取到 master 分支下的 config-dev.yml 檔案內容,

 

 

 

 

3、獲取 Git 中組態檔的常見 HTTP 格式

(1)格式說明

【三個引數:】
    label:        分支名
    application:  應用名(服務名)
    profile:      環境
注:
    提交到 Git 的組態檔名 一般由 application 與 profile 組成,
    其命名風格一般為: application-profile.yml 或者 application-profile.properties,
比如:
    config-dev.yml 、config-prod.yml 等,
    
【HTTP 格式:】
    /{label}/{application}-{profile}.yml   或者  /{label}/{application}-{profile}.properties    
    /{application}/{profile}/{label}
比如:
    /master/config-dev.yml
等價于
    /config/dev/master
注:
    master 可以省略,默認為 master,即 也等價于 /config-dev.yml

 

 

 

 

 

 

4、搭建客戶端(Config Client)

(1)新建一個子工程 config_client_9200,作為 Config Client
Step1:
  修改 父工程、當前工程 pom.xml 檔案,并引入相關依賴,
  此處以 Eureka 作為服務注冊中心,需要引入相關依賴,

【依賴:】
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

 

 

 

Step2:
  修改組態檔(bootstrap.yml),

【注意:】
    Config Client 組態檔是 bootstrap.yml,而非 application.yml,
注:
    bootstrap.yml 優先級比 application.yml 高(即 bootstrap.yml 先加載),
    Config Client 啟動后,會根據 bootstrap.yml 配置的 Config Server 資訊與 Config Server 進行系結,
    從而獲取到 Config Server 中存盤在 Git 的配置資訊, 
    
【bootstrap.yml】
server:
  port: 9200
spring:
  application:
    name: config_client
  cloud:
    # 系結配置中心,即 http://localhost:9100/master/config-dev.yml
    config:
      # 分支名稱
      label: master
      # 組態檔的名稱
      name: config
      # 后綴名
      profile: dev
      # config server 配置中心地址
      uri: http://localhost:9100

eureka:
  instance:
    appname: config_client # 優先級比 spring.application.name 高
    instance-id: ${eureka.instance.appname} # 設定當前實體 ID
  client:
    register-with-eureka: true # 默認為 true,注冊到 注冊中心
    fetch-registry: true # 默認為 true,從注冊中心 獲取 注冊資訊
    service-url:
      # 指向 注冊中心 地址,也即 eureka_server_7000 的地址,
      defaultZone: http://localhost:7000/eureka

 

 

 

Step3:
  撰寫 TestController 進行測驗,
  其中使用 @Value 注解用于 引入 Git 中存盤的組態檔中的內容,
注:
  初始啟動服務時,若 config client 系結 config server 失敗,即獲取不到 Git 中的配置資訊時,@Value 將會導致服務啟動失敗,

【TestController】
package com.lyh.springcloud.config_client_9200.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/config")
public class TestController {

    @Value("${config.info}")
    private String info;

    @GetMapping("/getInfo")
    public String getInfoAndMessage() {
        String result = "";
        if (info != null) {
            return "success " + info + "\n";
        }
        return "error";
    }
}

 

 

 

Step4:
  修改 Git 倉庫中 config-dev.yml 檔案如下:

【config-dev.yml:】
config:
  info: helloworld!!!

 

 

 

Step5:
  測驗,啟動 eureka_server_7000、config_server_9100、config_client_9200,
  前面 bootstrap.yml 配置的是 獲取 http://localhost:9100/master/config-dev.yml 中的內容,
  config client 成功啟動后,即可獲取 config-dev.yml 內容,從而 @Value 注入成功,成功回傳,
注:
  若 config client 啟動時,可能由于 @Value 注入失敗,從而導致 服務將啟動失敗,
可能原因:
  config server 配置錯誤,config client 不能正常系結 config server,
  config server 正常,但是 config-dev.yml 檔案不存在,
  config-dev.yml 檔案存在,但其中并不存在 config.info,

 

 

 

5、存在的問題(重繪問題)

(1)問題

【問題:】
    通過上面 config server 以及 config client 搭建,
    config client 已經能成功通過 config server 獲取到 Git 存盤的配置資訊,
但是存在一個問題:
    在 config client 以及 config server 服務均啟動后,再去修改 Git 中的組態檔,
    此時會發現 config server 能正常獲取最新的 配置資訊,但是 config client 獲取的仍是原來的值,
    只有重啟 config client 服務后才能正常獲取到最新的配置資訊,
    重啟肯定是不可取的方案,那么如何解決呢?

【解決方案一:】
    引入 actuator,借助其進行重繪,重新加載,
缺點:
    需要手動觸發 POST 請求,訪問 refresh 埠(http://localhost:9200/actuator/refresh),
    當然可以寫個腳本,定時發送請求,進行重繪,

【解決方案二:】
    方案一對于每個微服務可能都需要執行一次或多次 POST 請求,用于重繪配置資訊,
    實作起來還是有點麻煩的,
    那么是否存在一種機制,使其一次通知,處處生效?
    這里就需要使用一下訊息總線 SpringCloud Bus(后續介紹,此處暫時略過),

 

(2)解決方案一(使用 actuator):
Step1:
  引入 actuator 依賴,

【依賴:】
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

 

 

 

Step2:
  配置暴露埠,主要是 refresh,其余的隨意(可以直接用 * 表示所有),

# 暴露監控端點
management:
  endpoints:
    web:
      exposure:
        # include: "refresh"
        include: "*"

 

 

 

Step3:
  在 TestController 上添加 @RefreshScope 注解,

@RestController
@RequestMapping("/config")
@RefreshScope
public class TestController {

    @Value("${config.info}")
    private String info;

    @GetMapping("/getInfo")
    public String getInfoAndMessage() {
        String result = "";
        if (info != null) {
            return "success " + info + "\n";
        }
        return "error";
    }
}

 

 

 

Step4:
  重新啟動 config client,此時獲取到的是最新的配置資訊,

 

 

 

再次修改 config-dev.yml 內容如下:

config:
  info: refresh

 

 

 

此時 config server 訪問到的是最新的配置資訊

 

 

 

但 config client 獲取的仍為上一次的配置資訊

 

 

 

使用 Postman 發送 POST 請求 http://localhost:9200/actuator/refresh 后,
config client 再次獲取的為最新的配置資訊,

 

 

 

三、引入訊息總線

1、問題與解決

【問題:】
前面使用 Spring Cloud Config 作為配置中心時,留了一個坑:
    更新 Git 存盤的組態檔后, Config Client 并不能實時的獲取到最新的配置, 
    Config Client 需要重啟服務 或者 借助 actuator 重繪配置,從而獲取到最新的組態檔資訊,
    
而微服務中,Config Client 數量將會越來越多,若每個 Config Client 都需要重啟 或者 發送 refresh 請求,其伴隨的影響還是有一些的,
那么能否實作自動重繪? 即修改完 Git 的組態檔后,Config Client 自動重繪獲取最新的配置,

【解決:】
    使用 Spring Cloud Bus 配合 Spring Cloud Config 可以實作配置的 自動重繪功能,

 

 

 

四、訊息總線 -- Bus

1、Bus 是什么?

(1)Bus 是什么?

【Spring Cloud Bus 是什么:】
    Spring Cloud Bus 是將 輕量級訊息系統 鏈接到 分布式系統節點 的框架,整合了 事件處理機制 和 訊息中間件的功能,
    其能 管理、傳播 需要在分布式系統中傳遞的訊息,可用于 廣播狀態變化(比如: 配置修改)、事件推送等,也可以作為微服務應用間的通信通道,

【Bus 支持的 訊息系統:】
    Spring Cloud Bus 目前支持兩種訊息系統: RabbitMQ 和 Kafka,
    使用時需要引入對應的依賴: spring-cloud-starter-bus-amqp 或 spring-cloud-starter-bus-kafka,

【理解一下訊息總線:】
    訊息總線 可以理解為 一個訊息中心(RabbitMQ、Kafka),系統中所有微服務實體 連接到 總線上,
    微服務實體可以向訊息中心發送訊息 或者 接收訊息(監聽訊息中心的訊息),
   訊息中心 產生的訊息被 所有微服務實體 監聽并消費,
比如:
    微服務實體 A 發送一條訊息到總線上,其余微服務實體 可以監聽到 這個訊息,并進行相應處理,
 
【官網地址:】
https://spring.io/projects/spring-cloud-bus
https://docs.spring.io/spring-cloud-bus/docs/current/reference/html/

 

(2)如何實作?
方式一:
  客戶端 Config Client 重繪,

 

 

 

【基本流程:】
Step1:
    更新 Git Repository 中的組態檔,
    
Step2:
    向客戶端 Config Client C 發送 POST 請求: /actuator/busrefresh,
    此時 Config Client C 根據 Config Server 獲取最新的組態檔,
    并且 Config Client C 向 訊息總線 Bus 發送一條訊息(即 表示需要 重繪),

Step3:
    Bus 接收訊息后,將訊息通知給其他 客戶端實體(Config Client A、Config Client B),
    
Step4:
    其他客戶端實體 接收到資訊后,即相當于重繪,根據 Config Server 獲取最新的組態檔,

至此,所有客戶端實體均可獲得最新的配置資訊,

【問題:】
    一般不使用 客戶端重繪, 因為 客戶端本身屬于 業務模塊,重繪功能并不屬于其業務功能,會破壞了其職責單一性,

 

方式二:
  服務端 Config Server 重繪,

 

 

 

【基本流程:】
Step1:
    更新 Git Repository 中的組態檔,
    
Step2:
    向服務端 Config Server 發送 POST 請求: /actuator/busrefresh,
    并且 Config Server 向 訊息總線 Bus 發送一條訊息(即 表示需要 重繪),

Step3:
    Bus 接收訊息后,將訊息通知給所有客戶端實體(Config Client A、Config Client B、Config Client C),
    
Step4:
    客戶端實體 接收到資訊后,即相當于重繪,根據 Config Server 獲取最新的組態檔,

至此,所有客戶端實體均可獲得最新的配置資訊,

 

2、使用 RabbitMQ 作為訊息中間件

(1)使用 docker-compose 在 CentOS7 上構建基本環境
  docker-compose 基本使用可參照:https://www.cnblogs.com/l-y-h/p/12622730.html#_label8_2

【構建 docker-compose.yml 如下:】
# 指定 compose 檔案版本,與 docker 兼容,高版本的 docker 一般使用 3.x,
version: '3.7'
# 定義需要管理的 所有服務 資訊
services:
  # 此處指的是服務的名稱
  rabbitmq:
    # 指定鏡像路徑(可以是遠程倉庫鏡像 或者 本地鏡像)
    image: rabbitmq:3.8.3-management
    # 指定容器的名稱(等同于 docker run --name)
    container_name: rabbitmq
    # 定義容器重啟策略,no 表示任何情況下都不重啟(默認),always 表示總是重新啟動,
    restart: always
    hostname: myRabbitmq
    # 定義 宿主機 與 容器的埠映射
    ports:
      - 15672:15672
      - 5672:5672
    # 定義 宿主機 與 容器的資料卷映射
    volumes:
      - /usr/mydata/rabbitmq/data:/var/lib/rabbitmq
    # 設定環境變數
    environment:
      # 設定 RabbitMQ 登陸用戶為 root,登陸密碼為 root(若未配置,默認為 guest)
      - RABBITMQ_DEFAULT_USER=root
      - RABBITMQ_DEFAULT_PASS=root

 

(2)啟動 RabbitMQ
  通過 docker-compose up -d 啟動 RabbitMQ 后,可以通過 15672 埠號訪問其 Web 頁面,
注:
  若為云服務器,需要配置安全組規則,開放 15672、5672 埠,
  15672 是 RabbitMQ 可視化 web 界面訪問埠,
  5672 是 RabbitMQ 訪問埠,

 

 

 

3、Config 整合 Bus

(1)Config Server 整合 Bus(RabbitMQ)
  此處采用方案二,在 服務端進行 重繪,所以 Config Server 需要引入 actuator 依賴,
Step1:
  在 config_server_9100 中引入 RabbitMQ 以及 actuator 依賴,

【依賴:】
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

 

 

 

Step2:
  在組態檔中,添加 RabbitMQ 配置,并暴露 Bus 重繪的埠(busrefresh),
  通過 /actuator/bus-refresh 訪問 busrefresh,

【application.yml:】
spring:
  # rabbitmq 配置
  rabbitmq:
    username: root
    password: root
    host: 120.26.184.41
    port: 5672

# 暴露監控端點(busrefresh,或者直接寫 *)
management:
  endpoints:
    web:
      exposure:
        # include: "*"
        include: "busrefresh"

 

 

 

(2)Config Client 整合 Bus(RabbitMQ)
Step1:
  config_client_9200 同樣需要引入 RabbitMQ 依賴,

【依賴:】
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

 

 

 

Step2:
  在組態檔中,添加 RabbitMQ 配置,

【bootstrap.yml:】
spring:
# RabbitMQ 相關配置
rabbitmq:
  username: root
  password: root
  host: 120.26.184.41
  port: 5672

 

 

 

(3)新增一個 Config Client
  新增一個與 config_client_9200 類似的 config_client_9201,模擬多實體重繪,
  構建步驟與 config_client_9200 相同,僅修改 埠號即可,
  為了與 config_client_9200 區別,config_client_9201 中不引入 actuator 依賴,

 

 

 

 

(4)測驗,
  分別啟動:eureka_server_7000、config_server_9100、config_client_9200、config_client_9201,

Step1:
  初始訪問組態檔情況如下:

http://localhost:9100/master/config-dev.yml
http://localhost:9200/config/getInfo
http://localhost:9201/config/getInfo

 

 

 

Step2:
  修改組態檔后,再次獲取組態檔如下:

http://localhost:9100/master/config-dev.yml
http://localhost:9200/config/getInfo
http://localhost:9201/config/getInfo

 

 

 

Step3:
  向 Config Server 發送 POST 請求 /actuator/bus-refresh,再次獲取組態檔:

POST 請求: http://localhost:9100/actuator/bus-refresh
http://localhost:9100/master/config-dev.yml
http://localhost:9200/config/getInfo
http://localhost:9201/config/getInfo

 

 

 

Step4(方案一:客戶端重繪,僅供參考):
  再次修改組態檔,此次給 9200 發送 POST 請求,
  由于 9200 配置了 actuator,且暴露端點為 *,可以執行 refresh、bus-refresh,
  當發送的 POST 請求為 refersh 時,此時只會更新自己的組態檔,9201 不會更改,

POST 請求: http://localhost:9200/actuator/refresh
http://localhost:9100/master/config-dev.yml
http://localhost:9200/config/getInfo
http://localhost:9201/config/getInfo

 

 

 

當發送的 POST 請求為 bus-refresh 時,9201 組態檔也會修改,

POST 請求: http://localhost:9200/actuator/bus-refresh
http://localhost:9100/master/config-dev.yml
http://localhost:9200/config/getInfo
http://localhost:9201/config/getInfo

 

 

 

Step5:
  指定端點進行更新,在 POST 請求后加上需要加上相關 微服務實體的資訊,
  一般為: spring.application.name:server.port
比如:
  config_client:9201 表示僅指定 config_cliet_9201 這個微服務進行更新,
  config_client:** 表示 config_client 相關所有微服務進行更新,

POST 請求: http://localhost:9100/actuator/bus-refresh/config_client:9201
http://localhost:9100/master/config-dev.yml
http://localhost:9200/config/getInfo
http://localhost:9201/config/getInfo

 

 

 

五、分布式鏈路追蹤

1、問題 與 解決

【問題:】
    在一個復雜的微服務系統中,一個客戶端發送的請求 可能會經過 多個服務節點,這些服務節點協同作業產生最終的請求結果,
    此時可以將請求經過的微服務 看成一條 服務呼叫鏈路(分布式服務呼叫鏈路),
    鏈路中任何一個服務出現了 高延遲 或者 錯誤 都將引起 整個請求失敗,
    
    當某個請求失敗,如何確定是哪個服務出現了問題?
    逐行看日志肯定是不可取的方法,是否存在簡便的工具幫助我們快速定位錯誤服務?

【解決:】
    采用 SpringCloud Sleuth,追蹤并展示服務呼叫鏈路,

 

2、分布式鏈路追蹤 -- Sleuth

(1)Sleuth 是什么?

【什么是 Sleuth:】
    Spring Cloud Sleuth 提供了一套完整的分布式服務追蹤解決方案,兼容 Zipkin,

    在一個復雜的微服務系統中,若某時處理了多個請求,那么僅通過 日志 很難判斷出 一個請求 需要被哪些微服務關聯,
    一般解決方法是 對于每個請求都傳遞一個唯一的 ID,并根據 ID 查找其日志,

    而 Sleuth 可以與 日志框架(Logback、SLF4J) 輕松集成,并通過獨特的識別符號來使用 日志跟蹤,從而便于分析服務呼叫鏈路,

    Sleuth 在分布式系統中追蹤 一個請求的處理程序(資料采集、資料傳輸、資料存盤、資料分析、資料可視化),通過可視化界面,可以便于監控微服務呼叫鏈路,

【官網地址:】
https://spring.io/projects/spring-cloud-sleuth
https://docs.spring.io/spring-cloud-sleuth/docs/current/reference/html/getting-started.html

 

(2)下載、啟動 Zipkin Server
  Zipkin 用于可視化界面,下載 jar 包直接啟動即可,

【下載地址:】
    http://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/
比如:
    http://dl.bintray.com/openzipkin/maven/io/zipkin/java/zipkin-server/2.12.9/zipkin-server-2.12.9-exec.jar

通過 java -jar zipkin-server-2.12.9-exec.jar 可以直接啟動,

 

 

 

通過 9411 埠即可進入可視化 Web 界面,
比如:http://120.26.184.41:9411/

 

 

 

3、簡單整合 Sleuth

(1)說明

【說明:】
    此處使用  eureka_server_7000、config_server_9100、config_client_9200、config_client_9201 進行演示,
其中:
    為了演示鏈路呼叫,請求經過 config_client_9201,呼叫 config_client_9200,再呼叫 config_server_9100,
    使用 openfeign 進行服務遠程呼叫,

 

(2)改造 config_server_9100
Step1:
  引入 sleuth 依賴,并修改組態檔,

【依賴:】
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-zipkin</artifactId>
</dependency>

【bootstrap.yml:】
spring:
  zipkin:
    base-url: http://120.26.184.41:9411
  sleuth:
    # 采樣率范圍為 0 ~ 1,1 表示 全部采集
    sampler:
      probability: 1

 

 

 

Step2:
  撰寫業務代碼,

【SleuthController】
package com.lyh.springcloud.config_server_9100.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RequestMapping("/sleuth")
@RestController
public class SleuthController {

    @Value("${server.port}")
    private String port;

    @GetMapping("/getInfo")
    public String getInfo() {
        return port;
    }
}

 

 

 

(3)改造 config_client_9200
Step1:
  引入 openfeign、sleuth 依賴,并修改組態檔,

【依賴:】
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

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

【bootstrap.yml】
spring:
  zipkin:
    base-url: http://120.26.184.41:9411
  sleuth:
    # 采樣率范圍為 0 ~ 1,1 表示 全部采集
    sampler:
      probability: 1

 

 

 

Step2:
  撰寫業務代碼,
  config_client_9200 遠程呼叫 config_server 服務,
  在啟動類上添加 @EnableFeignClients 注解,

【SleuthService:】
package com.lyh.springcloud.config_client_9200.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;

@FeignClient(value = "CONFIG-SERVER")
@Component
public interface SleuthService {
    @GetMapping("/sleuth/getInfo")
    String getInfo();
}

【SleuthController】
package com.lyh.springcloud.config_client_9200.controller;

import com.lyh.springcloud.config_client_9200.service.SleuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/sleuth")
public class SleuthController {

    @Autowired
    private SleuthService sleuthService;

    @Value("${server.port}")
    private String port;

    @GetMapping("/getInfo")
    public String getInfo() {
        return sleuthService.getInfo() + "current port : " + port;
    }
}

 

 

 

(4)改造 config_client_9201
  config_client_9201 與 config_client_9200 修改代碼類似,只是 config_client_9201 遠程呼叫的是 config_client_9200 服務,

 

 

 

(5)測驗
  依次啟動 eureka_server_7000、config_server_9100、config_client_9200、config_client_9201 服務,并呼叫其方法,

 

 

 

 

 

 

 

 

(6)演示服務呼叫錯誤
  如下圖,在 config_client_9200 中模擬錯誤呼叫,并再次發送請求給 config_client_9201,

 

 

 

 

 

 

 

 

4、鏈路標識、日志整合

(1)鏈路標識
  通過上面的截圖,每個鏈路點開后,均有三個 ID:traceID,spanID,parentID,

【ID:】
    traceID 表示請求鏈路的唯一標識,當前鏈路中,每個服務節點均包含同一個 traceID,表示屬于當前鏈路,
    spanID 表示每個服務節點的 ID,用于區分鏈路中的每個請求,
    parentID 表示當前請求的父服務 ID,即用于關聯鏈路中的請求,

 

 

 

(2)日志整合
  如下圖,在 config_client_9200 中列印日志,并再次發送請求給 config_client_9201,
  日志輸出格式為:[application name, traceId, spanId, export],
注:
  application name 表示應用名,
  export 布爾型別,表示是否將資訊輸出到 zipkin 進行收集與展示,

【SleuthController:】
package com.lyh.springcloud.config_client_9200.controller;

import com.lyh.springcloud.config_client_9200.service.SleuthService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/sleuth")
public class SleuthController {

    @Autowired
    private SleuthService sleuthService;

    private final Logger logger = LoggerFactory.getLogger(SleuthController.class);

    @Value("${server.port}")
    private String port;

    @GetMapping("/getInfo")
    public String getInfo() {
        logger.info("test");
        return sleuthService.getInfo() + "current port : " + port;
    }
}

 

 

六、配置中心 Nacos

未完待續,,,

 

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/263640.html

標籤:Java

上一篇:java 基礎語法學習

下一篇:面試被問Java序列化和反序列化為什么要實作Serializable介面

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more