溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Seata 中怎么動態(tài)配置訂閱與降級

發(fā)布時間:2021-08-10 13:54:38 來源:億速云 閱讀:155 作者:Leah 欄目:大數(shù)據(jù)

這篇文章將為大家詳細講解有關(guān)Seata 中怎么動態(tài)配置訂閱與降級,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

動態(tài)配置訂閱

Seata 配置中心有一個監(jiān)聽器基準接口,它主要有一個抽象方法和 default 方法,如下:

io.seata.config.ConfigurationChangeListener

Seata 中怎么動態(tài)配置訂閱與降級

該監(jiān)聽器基準接口主要有兩個實現(xiàn)類型:

  1. 實現(xiàn)注冊配置訂閱事件監(jiān)聽器:用于實現(xiàn)各種功能的動態(tài)配置訂閱,比如 GlobalTransactionalInterceptor 實現(xiàn)了 ConfigurationChangeListener,根據(jù)動態(tài)配置訂閱實現(xiàn)的動態(tài)降級功能;

  2. 實現(xiàn)配置中心動態(tài)訂閱功能與適配:對于目前還沒有動態(tài)訂閱功能的 file 類型默認配置中心,可以實現(xiàn)該基準接口來實現(xiàn)動態(tài)配置訂閱功能;對于阻塞訂閱需要另起一個線程去執(zhí)行,這時候可以實現(xiàn)該基準接口進行適配,還可以復用該基準接口的線程池;以及還有異步訂閱,有訂閱單個 key,有訂閱多個 key 等等,我們都可以實現(xiàn)該基準接口以適配各個配置中心。

這里就用默認的 file 配置中心,以它的實現(xiàn)類 FileListener 舉例子,它的實現(xiàn)邏輯如下:

Seata 中怎么動態(tài)配置訂閱與降級

如上,

  • dataId:為訂閱的配置屬性;

  • listener:配置訂閱事件監(jiān)聽器,用于將外部傳入的 listener 作為一個 wrapper,執(zhí)行真正的變更邏輯,這里特別需要注意的是,該監(jiān)聽器與 FileListener 同樣實現(xiàn)了 ConfigurationChangeListener 接口,只不過 FileListener 是用于給 file 提供動態(tài)配置訂閱功能,而 listener 用于執(zhí)行配置訂閱事件

  • executor:用于處理配置變更邏輯的線程池,在 ConfigurationChangeListener#onProcessEvent 方法中用到。

FileListener#onChangeEvent 方法的實現(xiàn)讓 file 具備了動態(tài)配置訂閱的功能,它的邏輯如下:

無限循環(huán)獲取訂閱的配置屬性當前的值,從緩存中獲取舊的值,判斷是否有變更,如果有變更就執(zhí)行外部傳入 listener 的邏輯。

ConfigurationChangeEvent 用于保存配置變更的事件類,它的成員屬性如下:

Seata 中怎么動態(tài)配置訂閱與降級

這里的 getConfig 方法是如何感知 file 配置的變更呢?我們點進去,發(fā)現(xiàn)它最終的邏輯如下:

Seata 中怎么動態(tài)配置訂閱與降級

發(fā)現(xiàn)它是創(chuàng)建一個 future 類,然后包裝成一個 Runnable 放入線程池中異步執(zhí)行,最后調(diào)用 get 方法阻塞獲取值,那么我們繼續(xù)往下看:

Seata 中怎么動態(tài)配置訂閱與降級

allowDynamicRefresh:動態(tài)刷新配置開關(guān);

targetFileLastModified:file 最后更改的時間緩存。

以上邏輯:

獲取 file 最后更新的時間值 tempLastModified,然后對比對比緩存值 targetFileLastModified,如果 tempLastModified > targetFileLastModified,說明期間配置有更改過,這時就重新加載 file 實例,替換掉舊的 fileConfig,使得后面的操作能夠獲取到最新的配置值。

添加一個配置屬性監(jiān)聽器的邏輯如下:

Seata 中怎么動態(tài)配置訂閱與降級

configListenersMap 為 FileConfiguration 的配置監(jiān)聽器緩存,它的數(shù)據(jù)結(jié)構(gòu)如下:

ConcurrentMap<String/*dataId*/, Set<ConfigurationChangeListener>> configListenersMap

從數(shù)據(jù)結(jié)構(gòu)上可看出,每個配置屬性可關(guān)聯(lián)多個事件監(jiān)聽器。

最終執(zhí)行 onProcessEvent 方法,這個是監(jiān)聽器基準接口里面的 default 方法,它會調(diào)用 onChangeEvent 方法,即最終會調(diào)用 FileListener 中的實現(xiàn)。

動態(tài)降級

有了以上的動態(tài)配置訂閱功能,我們只需要實現(xiàn) ConfigurationChangeListener 監(jiān)聽器,就可以做各種各種的功能,目前 Seata 只有動態(tài)降級有用到動態(tài)配置訂閱的功能。

在「Seata AT 模式啟動源碼分析」這篇文章中講到,Spring 集成 Seata 的項目中,在 AT 模式啟動時,會用 用GlobalTransactionalInterceptor 代替了被 GlobalTransactional 和 GlobalLock 注解的方法,GlobalTransactionalInterceptor 實現(xiàn)了 MethodInterceptor,最終會執(zhí)行 invoker 方法,那么想要實現(xiàn)動態(tài)降級,就可以在這里做手腳。

  • 在 GlobalTransactionalInterceptor 中加入一個成員變量:

private volatile boolean disable;

在構(gòu)造函數(shù)中進行初始化賦值:

Seata 中怎么動態(tài)配置訂閱與降級

ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION(service.disableGlobalTransaction)這個參數(shù)目前有兩個功能:

  1. 在啟動時決定是否開啟全局事務(wù);

  2. 在開啟全局事務(wù)后,決定是否降級。

  • 實現(xiàn) ConfigurationChangeListener:

Seata 中怎么動態(tài)配置訂閱與降級

這里的邏輯簡單,就是判斷監(jiān)聽事件是否屬于 ConfigurationKeys.DISABLE_GLOBAL_TRANSACTION 配置屬性,如果是,直接更新 disable 值。

  • 接下來在 GlobalTransactionalInterceptor#invoke 中做點手腳

Seata 中怎么動態(tài)配置訂閱與降級

如上,disable = true 時,不執(zhí)行全局事務(wù)與全局鎖。

  • 配置中心訂閱降級監(jiān)聽器

io.seata.spring.annotation.GlobalTransactionScanner#wrapIfNecessary

Seata 中怎么動態(tài)配置訂閱與降級

關(guān)于Seata 中怎么動態(tài)配置訂閱與降級就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI