開發(fā)痛點
先來張圖看下吧垄分。
1. 邏輯散亂到幾個service中,大量的transaction script類代碼娃磺。
2. 一部分邏輯就花了200多行锋喜,大量平鋪代碼,難以復用豌鸡。
3. 充斥著大量入?yún)⒑侔悖S護性極低。
4. 等等等等……
原始思路
·?對于渠道路由于后期肯定是需要有很多可變因素涯冠,步驟的炉奴, 所以需要考慮流程可編排 便于后期動態(tài)調(diào)整。
·?流程可控后為保證數(shù)據(jù)隨時可用蛇更,可傳遞考慮 控制流與數(shù)據(jù)流分離原則瞻赶。
·?結(jié)合路由領(lǐng)域來說,需要實現(xiàn) 過濾派任、規(guī)則執(zhí)行 等特殊功能組件砸逊。考慮PipeLine管道模式 進行實現(xiàn)掌逛。·?
·?具體領(lǐng)域邏輯中有: 不同PaymentMethod师逸、 不同版本setting數(shù)據(jù)等都會綜合影響整個渠道過濾流程,考量因素差異性比較大豆混,考慮不同代碼實體實現(xiàn)主要變化點邏輯隔離 篓像。
演化歷程
以下總結(jié)了一下重構(gòu)的整個的思考過程。
· 按照之前原始思路定好了主要組件與設(shè)計框架開發(fā)皿伺。 →
·?后來發(fā)現(xiàn)setting的不同version與不同paymentMethod都可以影響Rules的組合與邏輯员辩。→
·?Pm鸵鸥、Version奠滑、Rule三者存在共同影響。
????a. 代碼硬隔離實現(xiàn)妒穴,靈活度低宋税,復雜度會高,需要新增許多類但執(zhí)行效率可控宰翅。
????b. 通過反射實現(xiàn)弃甥,靈活度高爽室,復雜度也高汁讼,但執(zhí)行效率偏低淆攻。
·?有木有一種方法既可以實現(xiàn)高靈活度的自定義又不需要用反射呢? →
·?組件嘿架、流程元數(shù)據(jù)配置化 + Spring Ioc + 無狀態(tài)組件 + 數(shù)據(jù)context流實現(xiàn)插件式開發(fā)瓶珊。 →
·?實現(xiàn)后發(fā)現(xiàn)SettingFilter中要體現(xiàn)version概念,又不想有version邏輯判斷與不同version的Pipe嵌入主流程耸彪∩∏郏→
·?想到用Strategy模式注入VersionalSettingService,讓其自感知版本并處理過濾SettingDimension邏輯。 →
·?為了組織Dimension在一起避免太多類蝉娜,需要統(tǒng)一Dimension接口唱较,考慮Enum組織SettingDimension。 →
·?分析發(fā)現(xiàn)原來考慮的每個Dimension需要統(tǒng)一的XXXDimensionSetting對象結(jié)果用于切面邏輯召川。Version需要VersionSettingResolver去處理不同version的setting到XXXDimensionSetting的適配邏輯南缓。? →
·?初期感覺代碼復雜度與空間復雜度過高,且不確定未來情況下統(tǒng)一的XXXDimensionSetting對象是否可滿足要求荧呐。 怎么辦汉形? →
·?進行爭議選項分析,具體見下節(jié)倍阐。綜合考慮選擇:移動計算到數(shù)據(jù)的模式概疆。考慮不同version數(shù)據(jù)維持在一個結(jié)構(gòu)中峰搪,讓計算邏輯XXXDimension在統(tǒng)一version的結(jié)構(gòu)中被運用岔冀。 →
·?則SetttingDimensionEnum也可以分不同version的Dimension。 →
·?在發(fā)現(xiàn)不同version的DimensionEnum中處理有些公共邏輯概耻,再用composite方式注入公共Dimension Strategy類 →
·?后發(fā)現(xiàn)有不同version的Resonpon邏輯要處理楣颠,抽象出VersionalResponseBuilder供調(diào)用 →
·?為了簡化依賴,統(tǒng)一用VersionalSettingService處理咐蚯,其代理VersionalResonseBuilder邏輯童漩。利用Kotlin委托實現(xiàn)Adaptor模式
最后細化細節(jié)技羔,譬如日志唯欣,緩存等。
爭議選型:
設(shè)計選型:
a方案: 以SettingDimension為主瘦材,新建settingObject與不同version的VersionResolver適配Dimension方法進行過濾期奔,讓數(shù)據(jù)適配邏輯侧馅。? 單獨SettingDimension,單獨VersionResolver呐萌,單獨SettingObject馁痴。
b方案: 以versionSetting為主,不同的VersionalSetting對應(yīng)于多個SettingDimension方法肺孤,不轉(zhuǎn)換對象罗晕,讓versionSetting結(jié)構(gòu)邏輯內(nèi)化到自身济欢,讓邏輯適配數(shù)據(jù)。
時間復雜度之爭:
時間復雜度基本與以前相同
空間復雜度之戰(zhàn):
移動計算到數(shù)據(jù)設(shè)計vs移動數(shù)據(jù)到計算設(shè)計
結(jié)論: 同樣策略模式-> 數(shù)據(jù)具體封閉在一起去除多余轉(zhuǎn)換與轉(zhuǎn)移小渊,比較靈活可控法褥。 計算策略移動到數(shù)據(jù)源去處理某些情況下前者更小空間復雜度,更靈活
d: 過濾維度? ? v: setting版本? p: 渠道數(shù)量
空間復雜度:m+v=o(n)vs? mv=o(n2)
譬如:數(shù)據(jù)有n個版本data酬屉,計算有m種strategy
data: 分為 d_v1,d_v2 ...., d_vn? ? ? ? ? ? strategy: 分為 s_1, s_1, ... s_m
目的基本就是:找到對應(yīng)策略執(zhí)行各種版本數(shù)據(jù)
方式一:if 移動數(shù)據(jù)到計算的方式, 這么設(shè)計:? ? strategy.process(common data) 半等。某些情況下,需要定義一個針對此strategy的common data呐萨,用于具體strategy 處理此common data結(jié)構(gòu)
方式二:if 移動計算到數(shù)據(jù)的方式, 這么設(shè)計:? ? data.processBy(strategy)? 此種情況下杀饵,數(shù)據(jù)具體封閉在data 類中,比較靈活可控谬擦。 計算策略移動到數(shù)據(jù)源去處理
實現(xiàn)步驟:
1. 定好基調(diào):
2. 快速實現(xiàn)框架流程:
3. 填入細節(jié):
4. 細節(jié)方案選型:
5. 評審與驗證方案
6. 實施方案并反復修改推演
7. 修繕細節(jié):優(yōu)化日志凹髓,緩存,錯誤處理等細節(jié)怯屉。
8. 測試與細節(jié)再修繕:
最終結(jié)構(gòu)
Configer: 配置管理器蔚舀,管理核心配置的獲取,
????包含 Pipe, Rule, Filter, Dimension, PaymentMethod, Version等編排元素的配置獲取锨络。
Pipe: 支持動態(tài)編排的管道系統(tǒng)赌躺。通過Configer獲取Pipe配置動態(tài)編排管道流程。
????DataAssemblerPipe:查詢setting數(shù)據(jù)羡儿,pipe line 數(shù)據(jù)裝配準備礼患。
????RulePipe:根據(jù)rule規(guī)則執(zhí)行rule邏輯。
????DecisionPipe:實現(xiàn)決策最終pmp的邏輯掠归。
Rule: 支持動態(tài)編碼的Rule規(guī)則缅叠。通過Configer獲取Rule配置動態(tài)編排管道流程。
????FiltersRule:支持過濾邏輯的規(guī)則虏冻。
????TransactionData Rule肤粱,RiskControlRule:暫未實現(xiàn)。
Filter: 支持動態(tài)編碼的Filter厨相。通過Configer獲取Filter配置動態(tài)編排管道流程领曼。
????SettingFilter:組織執(zhí)行版本化的setting的過濾。
????ProbabilityFilter:根據(jù)概率邏輯執(zhí)行過濾蛮穿。
VersionalSettingService: 支持版本化的setting服務(wù)庶骄。 通過Configer獲取Dimension配置動態(tài)編排SettingDimension執(zhí)行流程。
????AssembleDimension:組織dimension流程践磅。
????Execute:執(zhí)行Dimension并過濾pmp单刁。
????VersionalResonpseBuilderHolder:委托相應(yīng)version的ResponseBuilder執(zhí)行buildResponse邏輯。
VersionalSettingDimension: 支持版本化的setting匹配維度
????組織各個版本的不同dimension數(shù)據(jù)府适,并調(diào)用DimensionStrategy匹配共有dimension邏輯羔飞。
實現(xiàn)
DimensionStrategy: setting維度匹配策略肺樟,校驗相關(guān)setting中相應(yīng)內(nèi)容是否匹配。
????包含PaymentMethod褥傍,Region儡嘶,TransactionCcy等策略
VersionalResponseBuilder:? 支持版本化的返回數(shù)據(jù)構(gòu)建器
SettingModel:? 具體setting領(lǐng)域?qū)ο?/b>
最終效果:
廢話不多說喇聊,上圖吧:
基本每個類代碼不超過200行恍风,各個組件按照意圖分離,流程控制可配置化
總結(jié)
· 實現(xiàn) Rules 規(guī)則組件統(tǒng)一控制各種規(guī)則執(zhí)行誓篱。
·?實現(xiàn)Filters 過濾器組件統(tǒng)一控制轉(zhuǎn)發(fā)與短路朋贬。
·?流程元數(shù)據(jù)配置化。通過組合維度可以靈活控制主要流程窜骄。
·?規(guī)則配置化锦募。利于插件式開發(fā)。
·?不同版本setting數(shù)據(jù)的一些共有邏輯內(nèi)置化到充血領(lǐng)域模型邻遏,便于復用糠亩。
重構(gòu)心得
·? 類比service mesh領(lǐng)域: 控制平面與數(shù)據(jù)平面分離
·? 類比大數(shù)據(jù)、邊緣計算領(lǐng)域: 移動計算邏輯到數(shù)據(jù)的設(shè)計方法 (某些情況下可提升靈活性准验、減少空間復雜度)
·? 漸進性設(shè)計:重構(gòu)一些赎线,多想備選方案,綜合比對后優(yōu)化
·? 架構(gòu)分析方法論: 設(shè)計 → 編碼-> 難點方案進行多維度選型 → 重設(shè)計與編碼 → 評估 → 再循環(huán)
未來展望:
routing service規(guī)劃:
????1. 統(tǒng)一setting獲取邏輯
????2. 加入更多日志
????3. 實現(xiàn)decision決策邏輯
????4. 實現(xiàn)配置運行時可編排
????5. setting調(diào)用并行
????6. 基于版本號的配置推拉機制
????7. 考慮多filter并行處理
基礎(chǔ)PipeLine庫規(guī)劃:
????1. PipeContext中支持通過配置自編排
????2. Pipe支持DSL編排
????3. Pipe支持版本化
????4. Pipe支持異步邏輯
????5. Pipe支持fork-join邏輯
????6. Pipe支持背壓緩沖機制
插件式開發(fā)規(guī)劃與設(shè)計
通過合理的設(shè)計糊饱,讓配置元數(shù)據(jù)的修改可動態(tài)下推到客戶端并解釋執(zhí)行垂寥,無需修改服務(wù)端代碼。 通過統(tǒng)一的控制平臺管理執(zhí)行規(guī)則另锋,實現(xiàn) 控制平面 + 數(shù)據(jù)平面 分離滞项。
1. execute client端
springboot插件:
????a. rule本地存儲(或本地文件等存儲):rule存儲(記錄具體rule規(guī)則,rule執(zhí)行代碼)夭坪,rule agent存儲(代理具體信息入端口地址等)文判,rule strategy存儲(記錄rule執(zhí)行策略,如是否開啟本地執(zhí)行開關(guān)室梅,降級律杠,熔斷,重試竞惋,指標等)
????b. 注冊rules 代碼編譯加載器(啟動時柜去,運行時執(zhí)行)
????c. 注冊代碼執(zhí)行器 -> 反射執(zhí)行rules代碼
????d. 注冊rule message(包含rule代碼)controller端口,接受信息
????e. 啟動rule job(比對本地存儲版本與最新版本拆宛,如果舊了嗓奢,拉取最新rules并執(zhí)行編譯加載邏輯;如果遠程服務(wù)不可用浑厚,暫停本地執(zhí)行邏輯股耽,快速報錯并開啟斷路器)
????f. 斷路器
????g. 遠程執(zhí)行代理(根據(jù)rule message信息加載遠程代理)根盒,當選擇遠程執(zhí)行時自動遠程調(diào)用
????h. 提供本地rule執(zhí)行入口方法
2. execute service:
????a. 提供rule存儲服務(wù)
????b. 提供安全認證服務(wù)
????c. 提供rule message發(fā)送消息中間件服務(wù)
????d. 提供rule message發(fā)送配置中心推送
3. 通用安全的配置下發(fā)協(xié)議:
????前期可考慮http實現(xiàn)簡單
4. msg載體中間件
????a. 中轉(zhuǎn)消息