1. 程式人生 > >Seata 配置中心實現原理

Seata 配置中心實現原理

Seata 可以支援多個第三方配置中心,那麼 Seata 是如何同時相容那麼多個配置中心的呢?下面我給大家詳細介紹下 Seata 配置中心的實現原理。

配置中心屬性載入

在 Seata 配置中心,有兩個預設的配置檔案:

file.conf 是預設的配置屬性,registry.conf 主要儲存第三方註冊中心與配置中心的資訊,主要有兩大塊:

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  # ...
}

config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "file"
  nacos {
    serverAddr = "localhost"
    namespace = ""
  }
  file {
    name = "file.conf"
  }
  # ...
}

其中 registry 為註冊中心的配置屬性,這裡先不講,config 為配置中心的屬性值,預設為 file 型別,即會載入本地的 file.conf 裡面的屬性,如果 type 為其它型別,那麼會從第三方配置中心載入配置屬性值。

在 config 模組的 core 目錄中,有個配置工廠類 ConfigurationFactory,它的結構如下:

可以看到都是一些配置的靜態常量:

REGISTRY_CONF_PREFIX、REGISTRY_CONF_SUFFIX:配置檔名、預設配置檔案型別;

SYSTEM_PROPERTY_SEATA_CONFIG_NAME、ENV_SEATA_CONFIG_NAME、ENV_SYSTEM_KEY、ENV_PROPERTY_KEY:自定義檔名配置變數,也說明我們可以自定義配置中心的屬性檔案。

ConfigurationFactory 裡面有一處靜態程式碼塊,如下:

io.seata.config.ConfigurationFactory

根據自定義檔名配置變數找出配置檔名稱與型別,如果沒有配置,預設使用 registry.conf,FileConfiguration 是 Seata 預設的配置實現類,如果為預設值,則會更具 registry.conf 配置檔案生成 FileConfiguration 預設配置物件,這裡也可以利用 SPI 機制支援第三方擴充套件配置實現,具體實現是繼承 ExtConfigurationProvider 介面,在META-INF/services/建立一個檔案並填寫實現類的全路徑名,如下所示:

第三方配置中心實現類載入

在靜態程式碼塊邏輯載入完配置中心屬性之後,Seata 是如何選擇配置中心並獲取配置中心的屬性值的呢?

我們剛剛也說了 FileConfiguration 是 Seata 的預設配置實現類,它繼承了 AbstractConfiguration,它的基類為 Configuration,提供了獲取引數值的方法:

short getShort(String dataId, int defaultValue, long timeoutMills);
int getInt(String dataId, int defaultValue, long timeoutMills);
long getLong(String dataId, long defaultValue, long timeoutMills);
// ....

那麼意味著只需要第三方配置中心實現該介面,就可以整合到 Seata 配置中心了,下面我拿 zk 來做例子:

首先,第三方配置中心需要實現一個 Provider 類:

實現的 provider 方法如其名,主要是輸出具體的 Configuration 實現類。

那麼我們是如何獲取根據配置去獲取對應的第三方配置中心實現類呢?

在 Seata 專案中,獲取一個第三方配置中心實現類通常是這麼做的:

Configuration CONFIG = ConfigurationFactory.getInstance();

在 getInstance() 方法中主要是使用了單例模式構造配置實現類,它的構造具體實現如下:

io.seata.config.ConfigurationFactory#buildConfiguration:

首先從 ConfigurationFactory 中的靜態程式碼塊根據 registry.conf 建立的 CURRENT_FILE_INSTANCE 中獲取當前環境使用的配置中心,預設為為 File 型別,我們也可以在 registry.conf 配置其它第三方配置中心,這裡也是利用了 SPI 機制去載入第三方配置中心的實現類,具體實現如下:

如上,即是剛剛我所說的 ZookeeperConfigurationProvider 配置實現輸出類,我們再來看看這行程式碼:

EnhancedServiceLoader.load(ConfigurationProvider.class,Objects.requireNonNull(configType).name()).provide();

EnhancedServiceLoader 是 Seata SPI 實現核心類,這行程式碼會載入 META-INF/services/META-INF/seata/目錄中檔案填寫的類名,那麼如果其中有多個配置中心實現類都被載入了怎麼辦呢?

我們注意到 ZookeeperConfigurationProvider 類的上面有一個註解:

@LoadLevel(name = "ZK", order = 1)

在載入多個配置中心實現類時,會根據 order 進行排序:

io.seata.common.loader.EnhancedServiceLoader#findAllExtensionClass:

io.seata.common.loader.EnhancedServiceLoader#loadFile:

這樣,就不會產生衝突了。

但是我們發現 Seata 還可以用這個方法進行選擇,Seata 在呼叫 load 方法時,還傳了一個引數:

Objects.requireNonNull(configType).name()

ConfigType 為配置中心型別,是個列舉類:

public enum ConfigType {
  File, ZK, Nacos, Apollo, Consul, Etcd3, SpringCloudConfig, Custom;
}

我們注意到,LoadLevel 註解上還有一個 name 屬性,在進行篩選實現類時,Seata 還做了這個操作:

根據當前 configType 來判斷是否等於 LoadLevel 的 name 屬性,如果相等,那麼就是當前配置的第三方配置中心實現類。

第三方配置中心實現類

ZookeeperConfiguration 繼承了 AbstractConfiguration,它的構造方法如下:

構造方法建立了一個 zkClient 物件,這裡的 FILE_CONFIG 是什麼呢?

private static final Configuration FILE_CONFIG = ConfigurationFactory.CURRENT_FILE_INSTANCE;

原來就是剛剛靜態程式碼塊中建立的 registry.conf 配置實現類,從該配置實現類拿到第三方配置中心的相關屬性,構造第三方配置中心客戶端,然後實現 Configuration 介面時:

就可以利用客戶端相關方法去第三方配置獲取對應的引數值了。

第三方配置中心配置同步指令碼

上週末才寫好,已經提交 PR 上去了,還處於 review 中,預估會在 Seata 1.0 版本提供給大家使用,敬請期待。

具體位置在 Seata 專案的 script 目錄中:

config.txt 為本地配置好的值,搭建好第三方配置中心之後,執行指令碼會將 config.txt 的配置同步到第三方配置中心。

更多精彩文章請關注作者維護的公眾號「後端進階」,這是一個專注後端相關技術的公眾號。
關注公眾號並回復「後端」免費領取後端相關電子書籍。
歡迎分享,轉載請保留出處。

相關推薦

Seata 配置中心實現原理

Seata 可以支援多個第三方配置中心,那麼 Seata 是如何同時相容那麼多個配置中心的呢?下面我給大家詳細介紹下 Seata 配置中心的實現原理。 配置中心屬性載入 在 Seata 配置中心,有兩個預設的配置檔案: file.conf 是預設的配置屬性,registry.conf 主要儲存第三方註冊中

kafka告警簡單方案 依賴配置中心實現注有@ConfigurationProperties的bean相關屬性重新整理 簡單封裝kafka相關的api

一、前言   為什麼要設計kafka告警方案?現成的監控專案百度一下一大堆,KafkaOffsetMonitor、KafkaManager、 Burrow等,具體參考:kafka的訊息擠壓監控。由於本小組的專案使用的kafka叢集並沒有被公司的kafka-manager管理,所以只能自己簡單做一個告警。

依賴配置中心實現注有@ConfigurationProperties的bean相關屬性重新整理

配置中心是什麼   配置中心,通過key=value的形式儲存環境變數。配置中心的屬性做了修改,專案中可以通過配置中心的依賴(sdk)立即感知到。需要做的就是如何在屬性發生變化時,改變帶有@ConfigurationProperties的bean的相關屬性。 配置中心原理   在讀配置中心原始碼的時候發

SpringCloud Config(配置中心)實現配置自動重新整理總結

一、實現原理 1、ConfigServer(配置中心服務端)從遠端git拉取配置檔案並在本地git一份,ConfigClient(微服務)從ConfigServer端獲取自己對應 配置檔案; 2、當遠端git倉庫配置檔案發生改變,ConfigServer如何通知到Conf

spring boot自動配置實現原理——@Conditional

spring 4中引入了@Conditional註解,可以讓spring在滿足特定條件時才將一個類註冊到spring容器中,具體的條件由org.springframework.context.annotation.Condition介面來描述,該介面的定義如下

多個datasource的配置實現原理

      一般情況下,一個專案中只會有一個datasource,但是在某些情況、或者業務需求的情況下會出現一個專案有多個datasource的情況,當滿足一定條件的時候,對資料庫的操作就會從一個一個datasource切換到另一個datasource. 那麼這種多資料來源的配置

log4j2 自動刪除過期日誌檔案配置實現原理解析

  日誌檔案自動刪除功能必不可少,當然你可以讓運維去做這事,只是這不地道。而日誌元件是一個必備元件,讓其多做一件刪除的工作,無可厚非。本文就來探討下 log4j 的日誌檔案自動刪除實現吧。 0. 自動刪除配置參考樣例: (log4j2.xml) <?xml version="1.0" enc

Seata 動態配置訂閱與降級實現原理

Seata 的動態降級需要結合配置中心的動態配置訂閱功能。動態配置訂閱,即通過配置中心監聽訂閱,根據需要讀取已更新的快取值,ZK、Apollo、Nacos 等第三方配置中心都有現成的監聽器可實現動態重新整理配置;動態降級,即通過動態更新指定配置引數值,使得 Seata 能夠在執行過程中動態控制全域性事務失效(

spring_cloud config 配置中心及利用Github實現自動化熱載入配置

    spring_cloud有著強大的生態支援,其自帶的分散式配置中心可以有效解決分散式環境中配置不統一的問題,提供一箇中心化的配置中心。並且依靠其spring_bus(rabbitMq提供訂閱)和github或者gitlab自帶的webhook(鉤子函式

SpringCloud利用Consul實現分散式配置中心

文章目錄 consul介紹 使用consul配置中心 將服務註冊到consul上 推送配置到consul配置中心 效果圖 consul介紹 Consul 是 HashiCorp 公司推出的開源工

基於Apollo實現.NET Core微服務統一配置(測試環境-單機) .NET Core微服務之基於Apollo實現統一配置中心

一、前言 注:此篇只是為測試環境下的快速入門。後續會給大家帶來生產環境下得實戰開發。 具體的大家可以去看官方推薦。非常的簡單明瞭。以下介紹引用官方內容: Apollo(阿波羅)是攜程框架部門研發的分散式配置中心,能夠集中化管理應用不同環境、不同叢集的配置,配置修改後能夠實時推送到應用端,並且具

pring-cloud-config+spring-cloud-bus(實現配置中心動態重新整理配置檔案)

前置條件 rabbitmq安裝 使用maven構建專案 安裝postman(方便傳送請求重新整理配置) 環境:springboot 2.0.6版本   建立專案config-server 專案結構

基於ZooKeeper實現簡單的配置中心

ZooKeeper節點的型別分為以下幾類:     1. 持久節點:節點建立後就一直存在,直到有刪除操作來主動刪除該節點     2. 臨時節點:臨時節點的生命週期和建立該節點的客戶端會話繫結,即如果客戶端會話失效(客戶端宕機或下線),這個節點自動刪除      3. 時序節點:建立節點是可以設定這個屬性,Z

Spring Cloud Config + Spring Cloud Bus + kafka實現配置中心配置動態更新

一、架構圖 當在 Git 倉庫中某個應用配置檔案中的引數更新後,只需要通過 POST方法訪問 config Server 的 /actuator/bus-refresh 介面,就可以讓所以的微服務節點更新配置。 在我們的 DEMO 中有一個 Config Server

使用棧實現配置的括號對齊以及棧的實現原理

丟擲問題:校驗字串中括號是否對應,並可以根據配置修改需要匹配的成對字元。 例:()()(())  OK ()[]{}{([])}  OK ((())]  NO 對應則返回true,若不對應則返回false C#程式碼如下(與java程式碼差距不大),使用棧(新進後出

Spring Boot + Spring Cloud 實現許可權管理系統 後端篇(二十三):配置中心(Config、Bus)

線上演示 使用者名稱:admin 密碼:admin 技術背景 如今微服務架構盛行,在分散式系統中,專案日益龐大,子專案日益增多,每個專案都散落著各種配置檔案,且隨著服務的增加而不斷增多。此時,往往某一個基礎服務資訊變更,都會導致一系列服務的更新和重啟,運維也是苦不堪言,而且還很容易出錯。於是,配置中心便由此

通過zookeeper實現配置中心熱更新

    程式碼意思是首先從系統配置中如tomcat配置中找到zkHost宣告zookeeper地址如“192.168.0.23:2181”,構建zookeeper連線客戶端,根據ZookeeperPropertiesConfigure中配置的初始引數locationList到zookeeper找到名稱為該值的

分散式配置中心——攜程Apollo(阿波羅)的實現

    分散式配置中心有很多,springcloud的config、百度的disconfig、攜程的apollo、淘寶的diamond。由於攜程的apollo極少的侵入性,以及面對springcloud開發,所以專案技術選型最終定為apollo。一、攜程apollo優點: 

Zookeeper 實現分散式配置中心

個人備忘 前言: zookeeper 五個功能點 1. master的管理,如amq 叢集,kafka叢集。 2. 分散式鎖(悲觀、樂觀) 3. 分散式配置中心。 4. 叢集的監管。 5. 釋出與訂閱(佇列)。 以上五點,都是zookeeper的

【CSII-PE】dmconfig.xml實現原理配置方法

在一部分bundle的程式碼中(例如com.csii.gateway.api),在META-INF目錄下有個peconfig目錄,其中有一個dmconfig.xml檔案。這個檔案中有一些配置資訊: <?xml version="1.0" encoding="UTF