導讀:今天我們聊一個技術改造,針對Spring的ApplicationEvent事件做下最佳化。總結本篇文章希望對從事相關工作的同學能夠有所幫助或者啟發 。
前言
作為合格的Java開發,對Spring中ApplicationEvent事件都非常瞭解。在同一JVM裡面我們可以透過釋出對應事件,然後透過監聽事件的方式實現單模組程式碼或邏輯上的最佳化調整。
比如我們在系統啟過程中會監聽系統啟動監聽器虛擬類用來完成SpringApplicationRunListener監聽。
系統內建banner處理
系統內建預設配置處理
logbak統一標準的配置
在單體應用中(同一JVM中)透過監聽事件的方式實現拓展無疑不錯的選擇。但是在微服務中如果我們需要釋出針對整個系統而言,釋出全域性事件。在各個微服務叢集節點都能接受到呢?
本篇主要分享改造Spring事件的過程分享。結本篇文章希望對從事相關工作的同學能夠有所幫助或者啟發 。
背景
目前市面上比較火的低程式碼平臺,目前核心就是表單引擎。一個表單可能對應對應一個數據源或多個。在引擎中不可能管理資料來源,只能透過各應用模組來拓展實現。
在表單引擎中宣告拓展資料來源,應用服務獨立拓展實現。
實現資料來源配置採集來建立可用資料來源,首先面對的是兩個事情。
應用服務都獨立啟動(先後順序),保證資料來源配置能實時同步至表單引擎構建源快取
應用服務和引擎服務啟動後,拓展源有變更及時通知引擎層更新資料來源
技術選型
採用Redis實現訊息佇列-釋出/訂閱模式
由表單引擎提供的Support 整合到業務模組,業務模組實現表單引擎拓展的資料來源來上報資料來源配置資訊(當然為了安全可以對資料庫使用者名稱密碼進行加密),宣告拓展服務必須實現。
@FormDataSourceExtension 資料來源拓展
是否支援外部資料來源拓展
模組實現申明是否開啟外部資料來源管理
可透過配置檔案注入記憶體變數重新整理配置開關{@value}
根據資料來源標識獲取資料來源配置
服務啟動時非同步載入資料來源;取資料來源時可能沒載入完成
該介面在表單資料來源管理器實時讀取遠端配置構建源提供給表單引擎使用
獲取模組拓展資料來源
模組實現資料來源拓展點提供資料來源掃描上報能力;
資料來源來源可以是內部獨立定義元件管理,也可以從整合平臺呼叫已配置完整的資料來源管理資訊
整個大致邏輯如下
基於MQ管理訊息佇列-釋出/訂閱模式
原理和上訴原理相似,基礎這個選擇。在於同事反饋SpringBoot 整合Redis 在某些版本的時候,應用服務叢集部署時候,某些節點無法訂閱到訊息問題,出現了訊息丟失。
如果出現這種情況,對應快取資料來源在某些節點是無法建立的,需要每次連結的時候重新建立。這樣一來效能問題就上來了所以採用了基於MQ管理訊息佇列,應用服務釋出資料來源變更,引擎層監聽。
實現方案在使用元件上做下調整即可
方案最佳化
如果沒有那麼多的中介軟體可以使用,採用原生的方式實現。
原生我們該如何實現呢?
或者對於中介軟體的使用在對於業務模組而言是不是不用那麼關注呢?
第一:
如果採用原生方案實現,在微服務中我們只能藉助註冊中心採集到的微服務節點的元資料來一一分發業務。透過應用ID找到所有存活節點來實現遠端呼叫通知。
第二:
結合前言中提到的Spring事件,仔細思考下。可否透過申明系統全域性的事件,通知到監聽的應用節點呢?
當然有,比如在配置中心我們統一修改配置如何分發到所有應用節點配置重新整理觸發?
釋出全域性事件
監聽全域性事件
總結
對技術探索都是循序漸進,對於對外服務提供基礎能力。儘可能封裝底層邏輯,方便後續升級和改造最佳化。本文章提到了基礎微服務的全域性拓展事件,實現原理可能會比直接採用原生的複雜、程式碼量也會多很多。
但是無意之中提出了“中介軟體的能力”便於服務與其他應用場景,總結本篇文章希望對從事相關工作的同學能夠有所幫助或者啟發
- END -
往期推薦
高併發場景下JVM調優實踐之路
SpringCloud Ribbon中的7種負載均衡策略!
JDK ThreadPoolExecutor核心原理與實踐
聊聊併發程式設計的10個坑
Nginx 透過 Lua + Redis 實現動態封禁 IP
分享、點贊、在看
,給個
3連擊
唄