一、計畫介紹
Gobrs-Async 是一款功能強大、配置靈活、帶有全鏈路異常回呼、記憶體最佳化、異常狀態管理於一身的高效能多執行緒並行編程和動態編排框架。為企業提供在復雜套用場景下動態任務編排的能力。針對於復雜場景下,異步執行緒復雜性、任務依賴性、異常狀態難控制性;
二、解決什麽問題
在開發復雜中台業務過程中,難免會遇到呼叫各種中台業務數據, 而且會出現復雜的中台數據依賴關系,在這種情況下。程式碼的復雜程度就會增加。如下圖所示:
在請求呼叫各大中台數據時,難免會出現多個中台數據互相依賴的情況,現實開發中會遇到如下場景。
並列常見的場景 1 客戶端請求伺服端介面,該介面需要呼叫其他N個微服務的介面
譬如 請求我的購物車,那麽就需要去呼叫使用者的rpc、商品詳情的rpc、庫存rpc、優惠券等等好多個服務。同時,這些服務還有相互依賴關系,譬如必須先拿到商品id後,才能去庫存rpc服務請求庫存資訊。最終全部獲取完畢後,或超時了,就匯總結果,返回給客戶端。
2 並列執行N個任務,後續根據這1-N個任務的執行結果來決定是否繼續執行下一個任務,如使用者可以透過信箱、手機號、使用者名稱登入,登入介面只有一個,那麽當使用者發起登入請求後,我們需要並列根據信箱、手機號、使用者名稱來同時查資料庫,只要有一個成功了,都算成功,就可以繼續執行下一步。而不是先試信箱能否成功、再試手機號。
再如某介面限制了每個批次的傳參數量,每次最多查詢10個商品的資訊,我有45個商品需要查詢,就可以分5堆並列去查詢,後續就是統計這5堆的查詢結果。就看你是否強制要求全部查成功,還是不管有幾堆查成功都給客戶做返回
再如某個介面,有5個前置任務需要處理。其中有3個是必須要執行完畢才能執行後續的,另外2個是非強制的,只要這3個執行完就可以進行下一步,到時另外2個如果成功了就有值,如果還沒執行完,就是預設值。
3 需要進行執行緒隔離的多批次任務。
如多組任務, 各組任務之間彼此不相關,每組都需要一個獨立的執行緒池,每組都是獨立的一套執行單元的組合。有點類似於hystrix的執行緒池隔離策略。
4 單機工作流任務編排。
5 其他有順序編排的需求。
三、核心能力
四、框架設計
Gobrs-Async 在設計時,就充分考慮了開發者的使用習慣, 沒有依賴任何中介軟體。對並行框架做了良好的封裝。主要使用
CountDownLatch
、
ReentrantLock
、
volatile
等一系列並行技術開發設計。
任務觸發器
任務流的啟動者, 負責啟動任務執行流
任務觸發器
負責解析使用者配置的規則,同時於Spring結合,將配置的 Spring Bean 解析成 TaskBean,進而透過解析引擎載入成 任務裝飾器。進而組裝成任務樹
任務啟動器
負責透過使用解析引擎解析的任務樹。結合 JUC 並行框架排程實作對任務的統一管理,核心方法有
trigger 觸發任務載入器,為載入任務準備環境
任務載入器
負責載入任務流程,開始呼叫任務執行器執行核心流程
load 核心任務流程方法,在這裏阻塞等待整個任務流程
getBeginProcess 獲取子任務開始流程
completed 任務完成
errorInterrupted 任務失敗 中斷任務流程
error 任務失敗
任務執行器
最終的任務執行,每一個任務對應一個
TaskActuator
任務的 攔截、異常、執行、執行緒復用 等必要條件判斷都在這裏處理
prepare 任務前置處理
preInterceptor 統一任務前置處理
task 核心任務方法,業務執行內容
postInterceptor 統一後置處理
onSuccess 任務執行成功回呼
onFail 任務執行失敗回呼
任務匯流排
任務流程傳遞匯流排,包括 請求參數、任務載入器、 響應結果, 該物件暴露給使用者,拿到匹配業務的數據資訊,例如:返回結果、主動中斷任務流程等功能 需要任務匯流排(TaskSupport)支持
核心類圖
五、落地場景
目前 Gobrs-Async 已經在京東商城商詳團隊落地使用,經受嚴酷的並行考驗。對各種中台呼叫應對自如
透過 Gobrs-Async 管理中台介面請求 耗時任務請求 請求依賴關系等核心場景。充分利用CPU資源
六、規則範例
場景一
如圖1-1
說明 任務A 執行完了之後,繼續執行 B、C、D
配置
gobrs:
async:
rules:
- name: "ruleName1"
content: "A->B,C,D"
場景二
如圖1-2
說明 任務A 執行完了之後執行B 然後再執行 C、D
配置
gobrs:
async:
rules:
- name: "ruleName1"
content: "A->B->C,D"
場景三
如圖1-3
說明 任務A 執行完了之後執行B、E 然後按照順序 B的流程走C、D、G。E的流程走F、G
配置
gobrs:
async:
rules:
- name: "ruleName1"
content: "A->B->C->D->G;A->E->F->G"
場景四
如圖1-4
說明 這種任務流程 Gobrs-Async 也能輕松支持
配置
gobrs:
async:
rules:
- name: "ruleName1"
content: "A->B->C,D,E;A->H->I,J,K"
場景五
如圖1-5
範例一
說明 A、B、C 執行完之後再執行D
配置
gobrs:
async:
rules:
- name: "ruleName1"
content: "A,B,C->D"
範例二
說明
A、B、C 任務任意一個執行完成,則立即執行任務D( 誰最快執行誰執行, 類似於任務流程競爭關系 ) 此時可以使用 配置關鍵字
:any
配置
gobrs:
async:
## :any 是關鍵字 表示任意 依賴的任務執行完成立即執行自己
rules:
- name: "ruleName1"
content: "A,B,C->D:any"
範例三
說明
A、B、C 任務任意一個執行完成,則立即執行任務D( 誰最快執行誰執行, 類似於任務流程競爭關系 ) 與範例不同的是, 如果 D拿到執行權後,會將自身所依賴的未完成的任務 強制中斷執行(避免浪費資源,業務執行等) 此時可以使用 配置關鍵字
:exclusive
配置
gobrs:
async:
## :exclusive 是關鍵字
rules:
- name: "ruleName1"
content: "A,B,C->D:any:exclusive"
範例四
同範例二有點類似,在範例二的場景下,無法根據某一個任務的執行成功或者失敗進行後續任務的處理,範例二完全根據執行緒排程執行的隨機順序進行執行,即誰先執行完 誰有資格繼續往下執行,所以如果想 執行結果的條件 即:
task
方法返回
true
則立即執行,返回false則不執行的判斷條件進行控制。那麽就有以下的實作方式。
原始碼下載地址:
https://gitee.com/dromara/gobrs-async.git
看到最後,如果這個計畫對你有用,一定要給我點個「 在看和贊 」。