渠道選取路由重構(gòu)

開(kāi)發(fā)痛點(diǎn)

先來(lái)張圖看下吧。


1. 邏輯散亂到幾個(gè)service中,大量的transaction script類代碼。

2. 一部分邏輯就花了200多行,大量平鋪代碼,難以復(fù)用。

3. 充斥著大量入?yún)?,維護(hù)性極低。

4. 等等等等……



原始思路


·?對(duì)于渠道路由于后期肯定是需要有很多可變因素,步驟的, 所以需要考慮流程可編排 便于后期動(dòng)態(tài)調(diào)整。

·?流程可控后為保證數(shù)據(jù)隨時(shí)可用,可傳遞考慮 控制流與數(shù)據(jù)流分離原則。

·?結(jié)合路由領(lǐng)域來(lái)說(shuō),需要實(shí)現(xiàn) 過(guò)濾、規(guī)則執(zhí)行 等特殊功能組件。考慮PipeLine管道模式 進(jìn)行實(shí)現(xiàn)。·?

·?具體領(lǐng)域邏輯中有: 不同PaymentMethod、 不同版本setting數(shù)據(jù)等都會(huì)綜合影響整個(gè)渠道過(guò)濾流程,考量因素差異性比較大,考慮不同代碼實(shí)體實(shí)現(xiàn)主要變化點(diǎn)邏輯隔離 。


利用PipeLine模式:獲取配置 →?根據(jù)不同paymentMethod組裝不同的rules →?轉(zhuǎn)發(fā)不同paymentMethod handler來(lái)隔離執(zhí)行具體邏輯 →?組裝執(zhí)行Rules →?決策Rules執(zhí)行結(jié)果 →?結(jié)果輸出




演化歷程

以下總結(jié)了一下重構(gòu)的整個(gè)的思考過(guò)程。

· 按照之前原始思路定好了主要組件與設(shè)計(jì)框架開(kāi)發(fā)。 →

·?后來(lái)發(fā)現(xiàn)setting的不同version與不同paymentMethod都可以影響Rules的組合與邏輯?!?

·?Pm、Version、Rule三者存在共同影響。

????a. 代碼硬隔離實(shí)現(xiàn),靈活度低,復(fù)雜度會(huì)高,需要新增許多類但執(zhí)行效率可控。

????b. 通過(guò)反射實(shí)現(xiàn),靈活度高,復(fù)雜度也高,但執(zhí)行效率偏低。


·?有木有一種方法既可以實(shí)現(xiàn)高靈活度的自定義又不需要用反射呢? →


·?組件、流程元數(shù)據(jù)配置化 + Spring Ioc + 無(wú)狀態(tài)組件 + 數(shù)據(jù)context流實(shí)現(xiàn)插件式開(kāi)發(fā)。 →

·?實(shí)現(xiàn)后發(fā)現(xiàn)SettingFilter中要體現(xiàn)version概念,又不想有version邏輯判斷與不同version的Pipe嵌入主流程?!?

·?想到用Strategy模式注入VersionalSettingService,讓其自感知版本并處理過(guò)濾SettingDimension邏輯。 →

·?為了組織Dimension在一起避免太多類,需要統(tǒng)一Dimension接口,考慮Enum組織SettingDimension。 →

·?分析發(fā)現(xiàn)原來(lái)考慮的每個(gè)Dimension需要統(tǒng)一的XXXDimensionSetting對(duì)象結(jié)果用于切面邏輯。Version需要VersionSettingResolver去處理不同version的setting到XXXDimensionSetting的適配邏輯。? →


·?初期感覺(jué)代碼復(fù)雜度與空間復(fù)雜度過(guò)高,且不確定未來(lái)情況下統(tǒng)一的XXXDimensionSetting對(duì)象是否可滿足要求。 怎么辦? →


·?進(jìn)行爭(zhēng)議選項(xiàng)分析,具體見(jiàn)下節(jié)。綜合考慮選擇:移動(dòng)計(jì)算到數(shù)據(jù)的模式。考慮不同version數(shù)據(jù)維持在一個(gè)結(jié)構(gòu)中,讓計(jì)算邏輯XXXDimension在統(tǒng)一version的結(jié)構(gòu)中被運(yùn)用。 →

·?則SetttingDimensionEnum也可以分不同version的Dimension。 →

·?在發(fā)現(xiàn)不同version的DimensionEnum中處理有些公共邏輯,再用composite方式注入公共Dimension Strategy類 →

·?后發(fā)現(xiàn)有不同version的Resonpon邏輯要處理,抽象出VersionalResponseBuilder供調(diào)用 →

·?為了簡(jiǎn)化依賴,統(tǒng)一用VersionalSettingService處理,其代理VersionalResonseBuilder邏輯。利用Kotlin委托實(shí)現(xiàn)Adaptor模式

最后細(xì)化細(xì)節(jié),譬如日志,緩存等。



爭(zhēng)議選型:

設(shè)計(jì)選型:

a方案: 以SettingDimension為主,新建settingObject與不同version的VersionResolver適配Dimension方法進(jìn)行過(guò)濾,讓數(shù)據(jù)適配邏輯。? 單獨(dú)SettingDimension,單獨(dú)VersionResolver,單獨(dú)SettingObject。

b方案: 以versionSetting為主,不同的VersionalSetting對(duì)應(yīng)于多個(gè)SettingDimension方法,不轉(zhuǎn)換對(duì)象,讓versionSetting結(jié)構(gòu)邏輯內(nèi)化到自身,讓邏輯適配數(shù)據(jù)。

B方案


時(shí)間復(fù)雜度之爭(zhēng):

時(shí)間復(fù)雜度基本與以前相同


空間復(fù)雜度之戰(zhàn):

移動(dòng)計(jì)算到數(shù)據(jù)設(shè)計(jì)vs移動(dòng)數(shù)據(jù)到計(jì)算設(shè)計(jì)

結(jié)論: 同樣策略模式-> 數(shù)據(jù)具體封閉在一起去除多余轉(zhuǎn)換與轉(zhuǎn)移,比較靈活可控。 計(jì)算策略移動(dòng)到數(shù)據(jù)源去處理某些情況下前者更小空間復(fù)雜度,更靈活

d: 過(guò)濾維度? ? v: setting版本? p: 渠道數(shù)量

空間復(fù)雜度:m+v=o(n)vs? mv=o(n2)

譬如:數(shù)據(jù)有n個(gè)版本data,計(jì)算有m種strategy

data: 分為 d_v1,d_v2 ...., d_vn? ? ? ? ? ? strategy: 分為 s_1, s_1, ... s_m

目的基本就是:找到對(duì)應(yīng)策略執(zhí)行各種版本數(shù)據(jù)

方式一:if 移動(dòng)數(shù)據(jù)到計(jì)算的方式, 這么設(shè)計(jì):? ? strategy.process(common data) 。某些情況下,需要定義一個(gè)針對(duì)此strategy的common data,用于具體strategy 處理此common data結(jié)構(gòu)

方式二:if 移動(dòng)計(jì)算到數(shù)據(jù)的方式, 這么設(shè)計(jì):? ? data.processBy(strategy)? 此種情況下,數(shù)據(jù)具體封閉在data 類中,比較靈活可控。 計(jì)算策略移動(dòng)到數(shù)據(jù)源去處理



實(shí)現(xiàn)步驟:

1. 定好基調(diào):

2. 快速實(shí)現(xiàn)框架流程:

3. 填入細(xì)節(jié):

4. 細(xì)節(jié)方案選型:

5. 評(píng)審與驗(yàn)證方案

6. 實(shí)施方案并反復(fù)修改推演

7. 修繕細(xì)節(jié):優(yōu)化日志,緩存,錯(cuò)誤處理等細(xì)節(jié)。

8. 測(cè)試與細(xì)節(jié)再修繕:




最終結(jié)構(gòu)



Configer: 配置管理器,管理核心配置的獲取,

????包含 Pipe, Rule, Filter, Dimension, PaymentMethod, Version等編排元素的配置獲取。


Pipe: 支持動(dòng)態(tài)編排的管道系統(tǒng)。通過(guò)Configer獲取Pipe配置動(dòng)態(tài)編排管道流程。

????DataAssemblerPipe:查詢setting數(shù)據(jù),pipe line 數(shù)據(jù)裝配準(zhǔn)備。

????RulePipe:根據(jù)rule規(guī)則執(zhí)行rule邏輯。

????DecisionPipe:實(shí)現(xiàn)決策最終pmp的邏輯。


Rule: 支持動(dòng)態(tài)編碼的Rule規(guī)則。通過(guò)Configer獲取Rule配置動(dòng)態(tài)編排管道流程。

????FiltersRule:支持過(guò)濾邏輯的規(guī)則。

????TransactionData Rule,RiskControlRule:暫未實(shí)現(xiàn)。


Filter: 支持動(dòng)態(tài)編碼的Filter。通過(guò)Configer獲取Filter配置動(dòng)態(tài)編排管道流程。

????SettingFilter:組織執(zhí)行版本化的setting的過(guò)濾。

????ProbabilityFilter:根據(jù)概率邏輯執(zhí)行過(guò)濾。


VersionalSettingService: 支持版本化的setting服務(wù)。 通過(guò)Configer獲取Dimension配置動(dòng)態(tài)編排SettingDimension執(zhí)行流程。

????AssembleDimension:組織dimension流程。

????Execute:執(zhí)行Dimension并過(guò)濾pmp。

????VersionalResonpseBuilderHolder:委托相應(yīng)version的ResponseBuilder執(zhí)行buildResponse邏輯。


VersionalSettingDimension: 支持版本化的setting匹配維度

????組織各個(gè)版本的不同dimension數(shù)據(jù),并調(diào)用DimensionStrategy匹配共有dimension邏輯。

實(shí)現(xiàn)


DimensionStrategy: setting維度匹配策略,校驗(yàn)相關(guān)setting中相應(yīng)內(nèi)容是否匹配。

????包含PaymentMethod,Region,TransactionCcy等策略


VersionalResponseBuilder:? 支持版本化的返回?cái)?shù)據(jù)構(gòu)建器


SettingModel:? 具體setting領(lǐng)域?qū)ο?/b>




最終效果:

廢話不多說(shuō),上圖吧:


基本每個(gè)類代碼不超過(guò)200行,各個(gè)組件按照意圖分離,流程控制可配置化



總結(jié)


· 實(shí)現(xiàn) Rules 規(guī)則組件統(tǒng)一控制各種規(guī)則執(zhí)行。

·?實(shí)現(xiàn)Filters 過(guò)濾器組件統(tǒng)一控制轉(zhuǎn)發(fā)與短路。

·?流程元數(shù)據(jù)配置化。通過(guò)組合維度可以靈活控制主要流程。

·?規(guī)則配置化。利于插件式開(kāi)發(fā)。

·?不同版本setting數(shù)據(jù)的一些共有邏輯內(nèi)置化到充血領(lǐng)域模型,便于復(fù)用。



重構(gòu)心得


·? 類比service mesh領(lǐng)域: 控制平面與數(shù)據(jù)平面分離

·? 類比大數(shù)據(jù)、邊緣計(jì)算領(lǐng)域: 移動(dòng)計(jì)算邏輯到數(shù)據(jù)的設(shè)計(jì)方法 (某些情況下可提升靈活性、減少空間復(fù)雜度)

·? 漸進(jìn)性設(shè)計(jì):重構(gòu)一些,多想備選方案,綜合比對(duì)后優(yōu)化

·? 架構(gòu)分析方法論: 設(shè)計(jì) → 編碼-> 難點(diǎn)方案進(jìn)行多維度選型 → 重設(shè)計(jì)與編碼 → 評(píng)估 → 再循環(huán)



未來(lái)展望:


routing service規(guī)劃:


????1. 統(tǒng)一setting獲取邏輯

????2. 加入更多日志

????3. 實(shí)現(xiàn)decision決策邏輯

????4. 實(shí)現(xiàn)配置運(yùn)行時(shí)可編排

????5. setting調(diào)用并行

????6. 基于版本號(hào)的配置推拉機(jī)制

????7. 考慮多filter并行處理


基礎(chǔ)PipeLine庫(kù)規(guī)劃:


????1. PipeContext中支持通過(guò)配置自編排

????2. Pipe支持DSL編排

????3. Pipe支持版本化

????4. Pipe支持異步邏輯

????5. Pipe支持fork-join邏輯

????6. Pipe支持背壓緩沖機(jī)制


插件式開(kāi)發(fā)規(guī)劃與設(shè)計(jì)

通過(guò)合理的設(shè)計(jì),讓配置元數(shù)據(jù)的修改可動(dòng)態(tài)下推到客戶端并解釋執(zhí)行,無(wú)需修改服務(wù)端代碼。 通過(guò)統(tǒng)一的控制平臺(tái)管理執(zhí)行規(guī)則,實(shí)現(xiàn) 控制平面 + 數(shù)據(jù)平面 分離。

1. execute client端

springboot插件:

????a. rule本地存儲(chǔ)(或本地文件等存儲(chǔ)):rule存儲(chǔ)(記錄具體rule規(guī)則,rule執(zhí)行代碼),rule agent存儲(chǔ)(代理具體信息入端口地址等),rule strategy存儲(chǔ)(記錄rule執(zhí)行策略,如是否開(kāi)啟本地執(zhí)行開(kāi)關(guān),降級(jí),熔斷,重試,指標(biāo)等)

????b. 注冊(cè)rules 代碼編譯加載器(啟動(dòng)時(shí),運(yùn)行時(shí)執(zhí)行)

????c. 注冊(cè)代碼執(zhí)行器 -> 反射執(zhí)行rules代碼

????d. 注冊(cè)rule message(包含rule代碼)controller端口,接受信息

????e. 啟動(dòng)rule job(比對(duì)本地存儲(chǔ)版本與最新版本,如果舊了,拉取最新rules并執(zhí)行編譯加載邏輯;如果遠(yuǎn)程服務(wù)不可用,暫停本地執(zhí)行邏輯,快速報(bào)錯(cuò)并開(kāi)啟斷路器)

????f. 斷路器

????g. 遠(yuǎn)程執(zhí)行代理(根據(jù)rule message信息加載遠(yuǎn)程代理),當(dāng)選擇遠(yuǎn)程執(zhí)行時(shí)自動(dòng)遠(yuǎn)程調(diào)用

????h. 提供本地rule執(zhí)行入口方法

2. execute service:

????a. 提供rule存儲(chǔ)服務(wù)

????b. 提供安全認(rèn)證服務(wù)

????c. 提供rule message發(fā)送消息中間件服務(wù)

????d. 提供rule message發(fā)送配置中心推送

3. 通用安全的配置下發(fā)協(xié)議:

????前期可考慮http實(shí)現(xiàn)簡(jiǎn)單

4. msg載體中間件

????a. 中轉(zhuǎn)消息

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容