(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 基礎語法學習
