百川倉配切量接口成長史

背景

百川專項是指物流統一打造企業級能力平臺,戰略上聚焦純配、倉配類業務主線,以提升前臺業務整體交付吞吐率爲核心目標,支撐物流開放領域解決方案和標準產品的快速交付實施。計劃以“百川”專項項目爲契機,加速推動BP團隊將ECLP中各自業務的單據和履約職能整理下沉到訂單中心和各自業務的履約層中,以實現業務閉環。業務系統交互圖如下:





 



圖中綠色部分就是判斷是否切量,從交互可以看出是否走百川完全取決於切量結果的判斷。那麼如何精準靈活的控制流量成爲切量系統的關鍵。

下面讓我們隨着切量接口的發展引出一些遇到問題,並在最後的設計中給出解答。

小樹剛發芽

針對倉配的架構升級專項重點是重構原有的eclp-isv、eclp-so、eclp-bd等系統,將原來職責混亂、代碼難以維護的老系統,分成接入層、訂單中心、履約層三層結構。各系統職責分明、流程清晰,且在各層支持不同業務的橫向擴展。這裏好處就不在這裏班門弄斧了。說回老系統,eclp-isv作爲之前的接單入口,承接了多種業務的倉配接單場景。在針對這個入口的切量過程中,目前是以中小件業務作爲先頭部隊打造三層標準能力,也是2022年切量的重點。所以,針對中小件業務,需要專項上上下下逐步賦能,逐步切量。

切量初始階段,項目組能看清的是我想要什麼流量,比如第一次切量,產品和研發確定其中一個事業部的單子百川可以承接。所以只需要按照事業部白名單切量就可以了。下面展示從ISV下單時切量判斷的系統交互時序圖。





 



PS: 這裏使用到的神行平臺作爲切量配置平臺,感興趣的可以瞭解下。圖中紅色部分就是切量接口交互過程。接口定義其實很簡單,就是傳入下單參數,返回布爾值。

快速成長





 

隨着標準能力不斷完善,事業部切入的越來越多。也帶來新的問題,單量較大的事業部可能覆蓋的功能較多,如上圖的A、B、C、D四個功能項。有的能力具備(圖中綠色部分),而個別能力還在補齊中(圖中灰色部分)。怎麼切量才能篩選出我們可以承接的量呢?

很容易想到就是在切量接口裏加規則,根據下單參數中某個標位或某幾個參數組合去剔除那些明確接收不了的量,讓它們走原流程下單。就這樣不斷迭代中,切量接口中從一個事業部白名單判斷到幾十種規則匹配,接口的代碼量也膨脹到上千行。

程序迭代的過程中,必然會帶來的維護成本提高。而作爲流量入口,規則可能是幾天一更新,也可能是一天更新好幾次。如何在一個方法上千行裏做到一天幾次迭代,且要保證沒有問題。一旦出問題,將承接不了的流量引入,三層可能就需要花費一週甚至數週時間去修復,相信所有人都會頭疼。

隨着切量進展更加深入,對於功能的開發週期經過了邏輯梳理、產品規劃、開發、測試、AB比對、uat驗證、上線。爲了保證上線的切量平穩,就需要線上灰度驗證,但是百川是多層結構,從上到下都搭建起灰度環境工作量較大,如何進行灰度,既能較少工作量又能保證穩定呢?

開枝散葉

2023年專項的目標已經從中小件業務擴展到大件、冷鏈、國際等業務線全面接入百川,而接單的入口都是eclp-isv,也就是所有業務公用一個切量接口。中小件切量積累的切量規則肯定跟其他業務線切量規則會衝突,如何將切量接口進行重構才能支持多業務線不同的切量規則呢?

上面提到的背景都是基於線上環境的。還有個不可忽視的重要手段,那就是AB環境。專項通常投入大量的人力物力在AB比對,就是爲了保證在人工無法梳理到場景,通過AB環境錄製線上流量的方式進行比對,反向輸出需求,進而達到功能全覆蓋。





 

AB環境需要的流量本質上是以線上規則爲基礎,刪除或修改某一個規則,組合成完整的AB錄製規則。例如上圖中D流量的錄製。

AB錄製規則有以下幾個特徵:

基於線上規則,只有部分改動
更新頻率比線上規則更加頻繁
每次規則調整到線上同步改動週期不確定,可能1天也可能一兩週甚至一兩個月。

基於以上的特點,那麼我們改如何設計AB錄製規則合理呢,畢竟AB分支和線上分支切量方法有一千多行,合併起來總讓人頭疼。



梳理

說了這麼多背景,相信大家對一個小小的切量接口是如何成長,又面臨那些困境有了一些瞭解。那麼審題之後,我們來梳理下有哪些痛點。

單方法內容過多,難以維護
方法在不同環境單獨實現邏輯,合併分支困難
切量方法不支持橫向擴展,多業務線無法做到規則隔離
新功能切到百川缺少灰度驗證

設計

我一直相信:針對痛點做出的設計纔是合理的

那麼針對上訴的痛點,我們一一思考如何通過設計來解決。

單方法內容過多

從根本上來看方法的職責,就是通過下單入參來匹配一串規則,規則都滿足就進行切量,否則不切量。那麼內容過多就需要進行拆分。將大方法拆成一個個小方法,依次執行,任意規則不匹配就中斷。這裏最關鍵的是如何拆分合理。那就要看方法內容的核心,在觀察和整理所有規則後,提煉出了場景的概念。可以將所有規則按相似含義歸類成一個個場景,比如事業部、承運商、加密、合同物流等等。這樣用場景命名每個規則,做到直觀清晰且語義明確,每個規則都高內聚低耦合。

下面就是定義每個切量規則的接口如下:

public interface RuleMatchPoint {
    /**
     * 切量規則
     * @param shuntContext 下單報文上下文
     * @return 切量規則結果
     */
    boolean match(ShuntContext shuntContext);
}

然後通過責任鏈模式依次串聯起所有切量規則,通常最簡單的方式就是利用Spring框架自動將RuleMatchPoint接口注入到一個List中,然後循環調用match方法。





 

PS:這裏只是展示,並非全部規則。

不同環境隔離

基於上面分析,AB環境的錄製規則其實就是基於線上切量規則,然後在某個場景做放開流量調整,得到想要的線上流量。而通過場景拆分,切量規則已經不在臃腫,所以合併線上更新只會在某個場景出現代碼衝突。所以我們核心解決兩個問題:

怎麼複用線上切量規則
怎麼實現AB環境個性化切量規則。

這兩個問題圍繞着解決切量規則的“複用”與“個性化”問題,那麼我們其實就可以將所有規則進行細分:

1. 線上切量規則(個性)
2. AB切量規則(個性)
3. 通用規則(複用)

而不同環境就用所屬的個性規則+通用規則組成完整的切量規則集合。





 



而實現方案Spring提供的@Profile註解可以完美支持,這裏需要額外約定將AB環境的規則類命名要加AB前綴,與線上規則類區分開。



不支持多業務線規則隔離

目前切量工作分爲系統入口和業務兩種維度,其實有些業務還包含標準和KA更細力度。這裏就大範圍劃分如下圖。

 ISV POP
中小件 ISV中小件切量規則 POP中小件規則
冷鏈 ISV冷鏈切量規則 POP冷鏈切量規則

PS:橫向爲接單系統入口維度,縱向爲業務維度。

我們約定一個名詞:業務身份業務身份=入口+業務。那麼一個業務身份對應一套切量規則,就類似一個業務身份對應一個流程編排。要做到根據業務隔離就要針對不同的業務身份定製不同的切量規則,說簡單就是給切量規則打標。

根據上面的表我們定義兩種維度的註解:

 @ISV @POP
@Small ISV中小件切量規則 POP中小件規則
@Cold ISV冷鏈切量規則 POP冷鏈切量規則

不同業務身份所屬的規則集合就找滿足註解的切量規則即可。例如想要執行ISV中小件切量規則就找所有帶有@ISV+@Small的RuleMatchPoint接口集合。



當流量從某種切量入口進入後就需要經歷兩個過程。

1. 業務身份確認,如何確認需要業務測提供規則。
2. 使用屬於當前業務身份的切量規則集合去判斷是否切量。

按照這兩點,業務切量模板就定義成:

public interface ShuntStrategy {

    /**
     * 業務身份匹配
     * @param shuntContext 切量上下文
     * @return 業務身份是否匹配 true-匹配 false-不匹配
     */
    boolean businessIdentityMatch(ShuntContext shuntContext);

    /**
     * 業務規則匹配
     * @param shuntContext 切量上下文
     * @return 業務規則是否匹配 true-匹配 false-不匹配
     */
    boolean businessRuleMatch(ShuntContext shuntContext);
}

抽象出這兩個過程後,我們以ISV入口爲例,其中包含中小件和冷鏈兩個業務,流程如下:





 



按照這種結構規劃後,每個流量只要從某個入口進入後依次進行業務身份判斷,直到找到合適業務身份,然後進行規則匹配,最終返回是否切量結果,如果沒有匹配的業務身份則不切量。



如何控制模板順序

其實業務模板其實是需要順序的,順序的控制可以使用Spring框架的@Order註解或XML配置都是合理的。至於哪個業務線在前哪個在後就要綜合業務流量規模和業務線其他屬性共同決定了。



如此設計後,將單一的業務線的規則集合就擴展到支持業務線維度的橫向擴展。而且新流程接入和某個業務線切量規則調整不會影響其他業務線。



我們還是設計了切量規則支持擴展功能。這是因爲在各個業務線切量週期、節奏都不相同。我們第一步是完成中小件業務承接,所以規則集合寫在切量應用中。而冷鏈、國際等其他業務線,將對應業務的流量是否切量的權限下發給各個業務線。這種權限下放,可以讓業務靈活控制切量,而避免多方協同出錯協同延時問題。



缺少灰度驗證

這裏的灰度驗證實際上是指找到線上符合驗證條件的流量,控制其中一小部分走到新流程中驗證功能正確性,其他流量還走原流程。分析這個需求可以提煉出兩點:

1. 找到符合條件的流量
2. 控制多少量允許進入新流程

找到符合條件流量容易,只要能說出條件就能寫出規則。那麼功能的重點就在如何實現控制流量,也就是限流。

通常限流採用redis,設置帶有過期時間的key,獲取key的值是否超過上限,超過限流,否則自增。這個用於灰度驗證的場景也很合適,那麼就需要考慮如何定義key合理。





 

限流配置比較簡單,這裏就不贅述了。

截止到目前,有實現的限流規則有30多個。將所有限流規則打包成一個切量規則,然後集成到切量規則責任鏈的最後一個節點即可完成限流集成。那麼切量規則已經支持按照業務身份分組了,限流規則是否需要也要分組呢?以圖中SoMark限流爲例,無論哪種業務都可能存在SoMark限流訴求,只不過限流的配置不同。所以設計要做到邏輯通用、配置根據業務身份獨立兩點。

邏輯通用:在切量規則註解中擴展一個@Common註解,每個業務都集成這個註解的切量規則。
配置獨立:當限流讀取配置時,根據所屬的業務身份取不同的限流配置。



除了上面提到四個痛點的設計之前還有包括冪等設計、數據統計設計等等,篇幅有限就不一一展示了。

全景展示

最終落地的結構如下圖所示:





 



總結

從一個小小的接口演變成如此支持業務擴展、入口擴展、環境擴展的“3D”接口。也是我從參與專項一路摸爬滾打至今的縮影吧。歡迎大家一起探討,有考慮不周的也歡迎指出。

其實我覺得,大到系統間規劃小到接口重構,相對於重要戰略落地、緊急需求上線來說,屬於重要不緊急的那一類。但不應該等等再說,而應該未雨綢繆,隨機應變。

感謝觀看。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章