一、背景
- 若一個完整流水線涉及到多個子模塊,如四個以上,如何快速排查問題;
- 任意一個子模塊出現異常不可避免,如何保證業務數據的正確性;
- 能不能及時發現錯誤,並終止錯誤的業務數據繼續向下執行;
- 項目中成員編碼水平不齊,怎樣阻止錯誤向下蔓延;
二、模塊化編程
模塊化編程是一種軟件設計技術,它強調將程序的功能分為獨立的,可互換的模塊,以使每個模塊都包含執行所需功能的一個方面所必需的一切。模塊接口表示該模塊提供和需要的元素。接口中定義的元素可由其他模塊檢測。該實現包含與接口中聲明的元素相對應的工作代碼。
使用模塊化編程,可以將關注點分離,從而使模塊執行邏輯上離散的功能,並通過定義明確的界面進行交互。通常,模塊形成有向無環圖(DAG)。在這種情況下,模塊之間的循環依賴關系被視為指示這些模塊應該是單個模塊。在模塊確實形成DAG的情況下,它們可以按層次結構進行排列,其中最低級別的模塊是獨立的,不依賴於其他模塊,而較高級別的模塊則依賴於較低級別的模塊。特定程序或庫是其自身層次結構中的頂層模塊,但又可以看作是較高級程序,庫或系統的較低層模塊。
三、不可信驗證思維
- 文學家說:寧可信其有,不可信其無。
- 數據庫專家說:這是一個悲觀鎖。
- 測試人員說:來一個破壞性測試。
- 吃虧上當的研發人員:拿到數據要時刻保持懷疑態度,先驗證再使用。謹慎校驗,謝絕背鍋。
- 合理拆分業務模塊,保證子模塊功能相對單一獨立,不同子模塊之間通過全局唯一的業務編碼關聯串行;
- 子模塊的所需業務數據通過全局唯一業務編碼獲取;
- 子模塊主動驗證上一個業務模塊產生的結果數據。驗證合格繼續處理,驗證失敗,終止流程並記錄失敗原因;
四、實例分析
- 案例背景
電商系統中存在分銷業務,特別是網紅時代,網紅開店賣貨也是一種分銷模式。如某一個分銷機構一個月有3000個訂單流水,這些訂單的實際收款流入到分銷機構。這3000個訂單在電商系統中未付款,處於未完結狀態。分銷機構定期向電商公司打款結算訂單流水。
參數1:訂單3000個。
參數2:分銷機構A。
參數3:分銷機構A提供N條打款流水記錄
- 模塊化拆分
電商系統要實現這一批訂單的結算功能,可基於模塊化編程開發,主流程參考如下:
對賬單:指分銷機構定期向電商公司打款結算的業務單號。
流水號:分銷打款的銀行流水信息。一個對賬單對應多條流水信息。
本例中不同模塊僅通過對賬單編號流轉(忌:上一個模塊向下一個模塊傳遞大量業務參數)。各個子模塊之間可通過事件,消息等中間件模式解耦,不同模塊應各自獨立。
后一個子模塊在處理業務時,根據對賬單號自己獲取所需數據,並驗證所取數據的正確性。
流程參考說明圖:
對賬單核銷時,考慮到訂單數據量大,可基於后台任務處理,采用訂單逐條核銷的模式實現。核銷流程參考如下:
一個訂單適配一條流水:支付流水額度大於訂單待核銷的額度
一個訂單適配多條流水:單條支付流水額度不足以核銷一個訂單的待支付金額
- 不可信驗證思維
- 生成對賬單模塊:驗證訂單基礎信息,訂單是否被核銷過,驗證支付流水信息,判斷支付流水信息是否還存在可用額度,是否正常。
- 核銷對賬單模塊:基於對賬單編碼,查詢對賬單基礎信息。如對賬單要對賬的金額,申請訂單的總核銷金額是否一樣。對賬單關聯的流水信息是否可用。
- 核銷內部實現模塊:采用模擬核銷,最終驗證所有訂單是否核銷完成,模擬核銷的金額額度扣款是否成功。
- 訂單流水完成:分析對應訂單的核銷日志,核銷金額是否與最初待核銷金額一致。
- 大忌
- 在生成對賬單模塊完成后,傳遞對賬單擴展信息給核銷對賬單模塊,核銷模塊直接使用接收到的參數進行業務處理。
- 核銷模塊使用流水信息時,獲取對賬單與關聯的流水信息直接使用,不驗證。
