動態

詳情 返回 返回

Phoenix框架 從0到1設計業務併發框架 怎麼組織設計一個框架 - 動態 詳情

上篇文章主要講了設計 Phoenix 框架前的遇到的問題和設計框架的思路 《 Phoenix 框架 從0到1設計業務併發框架 小米商城產品站革新之路》,本篇文章主要講一下如何設計框架的。

不死鳥併發框架,是自動構建有向圖按照深度進行構建併發組並進行併發調用結果的框架。

產品站業務靜態接口與動態接口都需要調用大量的後台服務進行獲取數據進行業務編排,而各個併發調用之間又相互存在依賴,採用併發組設計拆解依賴,同時併發控制調用,BO to DTO 採用統一的 Transfer 層進行設計,開發人員只需要關係定義每次調用事件的 Task 和 Transfer 代碼邏輯的書寫,直接返回業務數據。

分層設計

名詞解釋

  • PhoenixFramework 不死鳥(鳳凰)框架,此業務併發框架的名稱;
  • Task 在業務併發中定義一次調用,可以是 HTTP、DUBBO 或者是 Redis 獲取、MySQL 讀庫操作;
  • Transfer 在業務定義中是一個子業務模塊的轉換邏輯將 BO 數據轉換為 DTO 數據;

Task 與 Trans 註解

怎麼定義 Task

在框架設計之初,我們內部有兩種方案,一種是繼承抽象類實現的方式,Task 通過繼承實現 PhoenixTask 類實現定義 Task,另外一種是採用註解的方式,將每個 Task 都定義成具有強約束的 Task ,並且把詳細的描述信息在註解中定義,給開發人員一目瞭然的設計思路。

經過內部討論,我們選擇了 Java 優秀的語言特性,註解的方式聲明定義 Task ,這樣的定義使得代碼簡潔明瞭,也有利於通過 Spring Bean 收集工具來收集我們的定義。

/**  
 * PhoenixTask 
 * 任務註解  
 *  
 * @author debuginn
 */
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
public @interface PhoenixTask {  
    String taskName();                     // 任務名稱  
    String[] beforeTaskName() default {};  // 前置任務  
    String[] filterPlatform() default {};  // 過濾渠道,黑名單  
    String[] taskBoName();                 // 任務生成的 BO 數據 用來校驗衝突  
}

PhoenixTask 註解定義非常簡單:

  • taskName用來標識任務名稱,採用枚舉,強制約束命名的唯一;
  • beforeTaskName前置任務,前面講到每個任務都是一次事件,區分前置任務是需要在併發調用的時候等待結果的返回,之後用來作為此 Task 調用的前置參數;
  • filterPlatform 過濾渠道,也就是黑名單的功能,但請求渠道在 Task 中聲明瞭黑名單,在併發執行的時候就自動屏蔽掉執行;
  • taskBoName任務轉化為 BO 的數據,通過接口調用或者中間件獲取數據,轉化為 Transfer 層使用的數據,在框架層做數據參數校驗;

怎麼定義 Trans

Trans 是 Transfer 的簡稱,同樣和 Task 設計一樣,也是採用註解的方式定義:

/**  
 * PhoenixTrans 
 * 業務編排註解  
 *  
 * @author debuginn 
 */
@Retention(RetentionPolicy.RUNTIME)  
@Target(ElementType.TYPE)  
public @interface PhoenixTrans {  
    String transName();             // 業務編排塊名稱  
    String apiName();               // 執行 使用併發 api  
    String[] tasks() default {};    // 依賴的 task 任務  
}

PhoenixTrans 註解定義同樣非常簡單:

  • transName用來標識業務編排塊名稱;
  • apiName 用來區分這個 Transfer 業務編排是隸屬於哪個併發 API 所屬的;
  • tasks就是定義依賴的 Task 任務有哪些,一個業務編排可能會利用 n 個 Task 返回的 BO 數據進行編排;
大家在這裏可能會比較疑惑,為啥 Task 中沒有定義 apiName 而是 Transfer 中定義的,是因為在設計中,為了便於後續 Task 可以被 n 個併發 API 共·用,這樣在 Transfer 定義了 apiName,之後通過 tasks 定義依賴的 Task 就可以推斷出這個 Task 目前是被哪一個併發 API 使用的。

怎麼收集 Task 和 Trans

自定義了 PhoenixTaskPhoenixTrans 註解,通過聲明一個 AnnotationProcessor 繼承 BeanPostProcessor 來進行收集定義的註解。

收集 Task 與 Trans

  • 首先是根據註解類收集上來對應的 Task 和 Trans;
  • 根據不同的 Trans 劃分不同的 API,收集不同 API 依賴的 Task;
  • 按照 Trans 是否進行依賴過濾使用到的 Task;
  • 根據 Task 之間的相互依賴關係,將 Task 進行分組;

劃分 API

劃分併發調用組

這樣就完成了對框架的分層與自動構建的設計,框架的設計主要的是要思考如何將實際業務中使用的模塊抽象化設計,同時要思考框架的擴展性與強約束性。

結尾

本篇文章主要講解我如何將業務與調用關係進行抽象成 Trans 與 Task 的,接下來我將講述併發框架併發線程池的核心設計、配置化思考、監控設計以及自動構建算法等系列文章。

如果你感興趣,關注我哦,歡迎互動與交流,讓我們一起變得更強~

Phoenix框架 從0到1設計業務併發框架:

  • Phoenix 框架 從0到1設計業務併發框架 小米商城產品站革新之路
本文首發於:blog.debuginn.com 公眾號:Debug客棧
user avatar king_wenzhinan 頭像 u_14540126 頭像 ahahan 頭像 kunaodejidan 頭像 lenve 頭像 huangxunhui 頭像 lu_lu 頭像 aipaobudezuoyeben 頭像 nianqingyouweidenangua 頭像 tuhooo 頭像 vistart 頭像 gvison 頭像
點贊 37 用戶, 點贊了這篇動態!
點贊

Add a new 評論

Some HTML is okay.