電商訂單履約-賣家發(fā)貨演化史
1、背景
訂單的履約之路就是從發(fā)貨開始,看似簡單的發(fā)貨功能,其背后卻藏著許多的小秘密。
發(fā)貨的業(yè)務特點:
- B端業(yè)務,性能要求不高,因為存在批量發(fā)貨的場景。
- 發(fā)貨時間比較分散,所以并發(fā)量不大。
- 業(yè)務復雜,涉及到N種訂單類型的發(fā)貨,不同的訂單類型有著不同的業(yè)務規(guī)則。
隨著公司業(yè)務的發(fā)展,訂單類型的增多,沒有進行抽象的發(fā)貨邏輯隨著迭代的推進難免會顯得落后。當然,在迭代的過程中,也一直在優(yōu)化,一直在演進,正所謂沒有最好,只有符合當前業(yè)務現狀的最合理。
2、一階段賣家發(fā)貨
圖片
賣家發(fā)貨在一開始的時候,有N個接口。比如,現貨單個發(fā)貨,現貨批量發(fā)貨,現貨極速發(fā)貨,App發(fā)貨,直發(fā)發(fā)貨,定制發(fā)貨等。
有這么多發(fā)貨接口也是我們平臺的業(yè)務特性決定的,現貨就是賣家發(fā)貨到平臺,直發(fā)就是賣家發(fā)貨到買家,不同的業(yè)務有不同的流程。除了接口多這個問題,另一個問題是邏輯分散,每個接口都是獨立的邏輯,大量重復代碼的出現極大地增加了維護的成本。
比較簡化的發(fā)貨流程如下:
- 參數校驗
- 一些業(yè)務校驗,比如訂單狀態(tài),發(fā)貨冷靜期等
- 核銷賣家優(yōu)惠
- 推狀態(tài)機
- 訂單數據修改保存
- 廣播發(fā)貨消息
- 下發(fā)入庫單
- 訂閱物流軌跡
- ……
在整個流程里面,存在很多可以優(yōu)化的點。如在訂單數據更新之后的很多操作都可以通過異步的方式去處理,這樣可以提高發(fā)貨整體的性能。
總結下之前賣家發(fā)貨存在的幾個問題:
- 對外接口多,難以維護
- 發(fā)貨業(yè)務跟訂單類型強綁定
- 內部邏輯分散,無業(yè)務全貌
- 整體性能偏差
3、二階段賣家發(fā)貨
3.1 業(yè)務改造
前面也提到了,目前發(fā)貨是基于訂單類型分類來進行編排。之所以要通過訂單類型去做分類是因為之前只有訂單類型,所有的業(yè)務都是根據訂單類型去做區(qū)分。主要還是沒有站在履約的視角下去做發(fā)貨這件事情,所以導致每加一種訂單類型,對發(fā)貨都有一定的影響。
在履約視角下,會有履約單。履約單上有履約模式,目前有現貨,直發(fā),倉發(fā),虛擬,服務單,跨境直發(fā),跨境現貨,跨境在倉。
履約模式是對貨品怎么從賣家交付到買家手里的一種業(yè)務模式,不同的模式在業(yè)務流程的處理上不一樣,在賣家發(fā)貨的場景下,只關注貨怎么到買家,而不需要關注訂單是什么類型。
- 現貨
現貨模式指的是賣家把貨發(fā)平臺,平臺質檢/鑒別合格后再把貨發(fā)給買家?,F貨類的訂單類型有普通現貨,極速現貨,極速預售,定金預售等。
- 直發(fā)
直發(fā)模式指的是賣家直接把貨發(fā)到買家。直發(fā)類的訂單類型有品牌直發(fā),定金預售直發(fā),拍賣直發(fā),眾籌直發(fā),盲盒直發(fā)等。
- 倉發(fā)
倉發(fā)模式指的是賣家提前將貨發(fā)到平臺倉庫,買家下單后直接從倉庫發(fā)出。
- 虛擬
虛擬模式指的是在線履約,無需快遞配送。虛擬類的訂單類型有隨心省,洗護卡,虛擬卡卷等。
- 服務單
服務單指的是定制類的服務,需要將貨品從平臺寄到服務商,服務商完成定制服務后再寄回平臺,再由平臺寄給買家。
從履約模式的劃分可以看的出來,每個業(yè)務場景都有一個訂單類型,但從履約的方式來說都一樣。二階段發(fā)貨會根據履約模式去做業(yè)務流程編排,不感知訂單類型,這樣就能沉淀平臺化的能力,而不是跟著上層業(yè)務每次都需要改變。如有特定的針對某種訂單類型的業(yè)務處理,這個邏輯會放在訂單側。
3.2 穩(wěn)定性改造
在穩(wěn)定性方面也做了一些改造,發(fā)貨雖然不是導購下單鏈路,但也是非常重要的一個節(jié)點。發(fā)貨有問題就會導致訂單狀態(tài)無法推進,后續(xù)會引發(fā)超時關單等問題,所以在穩(wěn)定性上必須嚴格保證。
整個發(fā)貨的操作,有失敗的會立刻告警出來,當然這里會屏蔽一些正常的業(yè)務校驗場景,否則告警太多就顯得毫無意義。同時也基于訂單目前現有的錯誤碼大盤構建了發(fā)貨的大盤,發(fā)貨失敗量,失敗的原因通過大盤一看便知有沒有問題。
圖片
3.3 業(yè)務感知
作為研發(fā)同學,無論是業(yè)務研發(fā)還是中間件研發(fā),都需要對自己負責的系統和功能的使用情況比較了解。構建業(yè)務大盤就是一種非常好的能夠實時感知業(yè)務情況的一種方式。
比如說在發(fā)貨場景我們需要感知的數據有如下:
- 總發(fā)貨量
- 各履約模式的發(fā)貨量,現貨 xxx,直發(fā) xxx,虛擬 xxx
- 各場景的發(fā)貨量,App xxx,商家后臺 xxx,開放平臺 xxx
- 發(fā)貨承運商分布情況,順豐 xxx ,京東 xxx
- 發(fā)貨方式分布情況,上門取件,自主發(fā)貨,普通履約(平臺下運單)
- ……
3.4 改造收益
這次改造的收益如下:
- 統一發(fā)貨接口
- 只有一個接口,支持所有的賣家發(fā)貨場景
- 接入成本低,接入方式簡單
- 統一發(fā)貨協議,支持多運單多訂單同時發(fā)貨
- 基于履約模式做業(yè)務編排,新增訂單類型無需改造
- 提升后續(xù)發(fā)貨相關開發(fā)效率
- 完善業(yè)務大盤,錯誤碼大盤
4、三階段賣家發(fā)貨
4.1 什么是業(yè)務身份?
我們做平臺化的業(yè)務,同時對多業(yè)務提供服務時,需要有標識能夠區(qū)分每一次業(yè)務服務請求的身份,這樣就可以提供差異化個性化的服務,我理解這就是業(yè)務身份。
就好比消費者去一家線下門店消費,商家會讓消費者辦會員卡,會員卡有不同的等級,比如黃金卡,鉑金卡等等。消費者每次去店里消費都會帶上這張卡,這張卡就是消費者的身份,商家也能根據這張卡來給消費者提供差異化的服務。
4.2 履約模式下賣家發(fā)貨面臨的問題
在構建業(yè)務身份之前,我們是基于履約模式去處理差異化的業(yè)務流程。也并不是說非得抽業(yè)務身份,而是到了某個階段,業(yè)務的復雜度不得不讓你改變現有模型,說白了就是沒辦法支持多變的業(yè)務,就算能支持,改動帶來的影響面比較大,對測試回歸的范圍比較廣。所以我們需要反思以什么樣的形式來解決復雜業(yè)務,同時又能支持后續(xù)業(yè)務的多變性,還能減少測試范圍,這就是我們構建業(yè)務身份的根本原因。
上面說的可能有點抽象,下面通過一個具體的例子來說明下目前遇到的問題以及用業(yè)務身份如何解決這個問題,如何獲得高擴展性。
在本文第四點 基于履約視角的賣家發(fā)貨中已經說明了最新的發(fā)貨是基于履約模式來進行業(yè)務編排。直發(fā)和現貨模式都是基于實物的履約模式,需要使用快遞發(fā)貨。但我們還有一種虛擬履約模式,虛擬履約是不需要快遞發(fā)貨,而是線上進行,比如月卡,游戲皮膚,票務(電子票)等等。
如下圖所示:
圖片
在虛擬模式中的票務目前僅僅支持電子票的形式,在最新的需求中,需要支持實體票。實體票默認都是快遞配送,如果購買時間臨近演出開始的時間,那么快遞配送在時間上肯定是不能滿足要求,這個時候另一種方式出現了,它就是現場取票。
此時可以看下圖,虛擬模式下又存在多種業(yè)務場景,當虛擬訂單需要走快遞配送的鏈路,現有基于履約模式的業(yè)務編排沒辦法支撐。如果不談合理性,只實現需求的話只能在虛擬模式下再開一條新流程,處理快遞配送的流程。但是快遞配送相關的流程在直發(fā)和現貨的模式下都是現成的,這樣做后續(xù)維護成本和理解成本太高,這就是基于履約模式的發(fā)貨目前面臨的業(yè)務擴展問題。
圖片
4.3 業(yè)務身份如何破局,提高擴展性
圖片
如上圖所示:底層能力不再跟履約模式進行一一綁定,而是基于業(yè)務場景進行了抽象。這樣做的好處在于這些底層能力可以被復用,怎么復用就需要抽象出具體的業(yè)務身份。
舉例說明:
現貨通用業(yè)務身份 對應的能力如下:
- 運單號校驗 需要
- 創(chuàng)建發(fā)貨批次單 不需要
- 優(yōu)惠核銷 需要
- 狀態(tài)機 現貨
現貨App業(yè)務身份 對應的能力如下:
- 運單號校驗 需要
- 創(chuàng)建發(fā)貨批次單 需要
- 優(yōu)惠核銷 需要
- 狀態(tài)機 現貨
虛擬通用業(yè)務身份 對應的能力如下:
- 運單號校驗 不需要
- 創(chuàng)建發(fā)貨批次單 不需要
- 優(yōu)惠核銷 不需要
- 狀態(tài)機 虛擬
虛擬快遞業(yè)務身份 對應的能力如下:
- 運單號校驗 需要
- 創(chuàng)建發(fā)貨批次單 不需要
- 優(yōu)惠核銷 不需要
- 狀態(tài)機 虛擬快遞
通過上面的例子我相信大家都看明白了業(yè)務身份的作用,結合業(yè)務抽象出業(yè)務身份,同時為業(yè)務身份綁定對應的能力,這樣就能完全的復用底層能力。
當然,這里的重點是如何提取出對應的業(yè)務身份,業(yè)務身份是一個多維度聚合的一個結果,并不是隨便編造出來就可以。以賣家發(fā)貨的場景來分析,業(yè)務差異性體現在下面幾個點上:
- 不同的端有不同的邏輯
這里的端指的是賣家發(fā)貨時使用的系統,比如App,商家后臺,開放平臺對接等等。
- 不同的履約模式有不同的邏輯
- 履約模式目前已經細分完成,有直發(fā),現貨,定制,虛擬等等。
所以我們的業(yè)務身份就是對應的端+履約模式,對于沒有差異性的可以定一個通用的業(yè)務身份,后面有差異性了再單獨提取出來。比如通用現貨,需要細分的那就是App現貨。
上面這個維度組成的業(yè)務身份能滿足大部分場景,還是有些場景無法滿足,那就是虛擬訂單走快遞配送的場景。也就是說我只能識別出當前的業(yè)務身份是虛擬模式,但是無法識別出虛擬模式下是要走快遞配送,還是現場取票,還是憑證發(fā)貨。
為此,增加了第三個維度來組成業(yè)務身份,這樣就能明確當前的業(yè)務身份需要做哪些事情。所以對于虛擬的業(yè)務身份就會有虛擬通用,虛擬快遞發(fā),虛擬現場取三個業(yè)務身份。
對業(yè)務身份來說,也是會隨著業(yè)務而進行演變,也許以后將整個履約鏈路標準化,提供給多業(yè)務使用,這個時候業(yè)務身份中就會增加非常重要的一個維度:租戶。
4.4 改造收益
4.4.1 高擴展性
高擴展性其實上面已經講過了,通過業(yè)務身份編排的方式輕松的就支持了虛擬訂單走快遞配送的履約方式。根本不需要在之前很多邏輯里面加 if 進行強判斷。
比如有個需求要對發(fā)貨時子母件(一個運單多個包裹)的場景進行攔截,只在某一種履約模式下進行攔截。這個時候我們就可以新增一個子母件攔截的基礎能力,分別是攔截和不攔截。
然后給需要攔截的業(yè)務身份配置上攔截,給不需要攔截的業(yè)務身份配置上不攔截,這樣就只有指定的場景才會用到子母件攔截的能力。如果后面其他模式也要支持攔截,直接改配置就可以了,無需改動底層業(yè)務代碼。
高擴展性的前提是有好的抽象和分層,發(fā)貨整體業(yè)務架構如下圖所示:
圖片
4.4.2 測試成本低
測試成本低主要體現在改動范圍都是可控的,因為整個發(fā)貨流程中都抽象出了具體的能力。比如說你改了A能力,A能力只作用在虛擬模式下,那么測試只需要回歸虛擬模式的流程即可。
以上面說的子母件攔截的場景來講,也只需要測試現貨模式,而且老邏輯都不用看,因為是新增的能力點,完全不會影響老的業(yè)務邏輯。
或者說在業(yè)務的發(fā)展下,新出現了一個業(yè)務身份,但是這個業(yè)務身份對應的能力都是之前已經存在的能力,只不過是有些能力不需要,這個時候只需要改兩個地方,一個是業(yè)務身份對應能力的配置,另一個是計算業(yè)務身份的邏輯,能夠根據某些條件決策出當前請求是這個新的業(yè)務身份。這個時候測試只需要簡單的驗證下即可,底層能力都是已經在使用的,不同的點只在于編排。
無論是新增,還是修改,還是重新編排。都能很明確的知道當前調整的范圍,這樣測試的成本自然也就比較低。不再需要像以前一樣,改動了幾行代碼,不清楚什么場景在使用,然后全部回歸一遍。
5、未來展望
5.1 底層能力的持續(xù)完善
目前發(fā)貨場景的底層能力數量不多,在某些場景還是會有簡單的if判斷邏輯。在目前看來這些場景還沒有特別復雜,隨著業(yè)務的發(fā)展和規(guī)則的變化,這些邏輯越來越復雜的時候,就需要繼續(xù)去提取出原子級別的能力。
能力的提取和業(yè)務身份的抽象是個漫長的過程,不存在一成不變的情況,只存在慢慢演進和優(yōu)化的過程。
5.2 業(yè)務身份的可視化編排
可視化編排在初期并不是重要的一環(huán),隨著底層能力越來越豐富,業(yè)務規(guī)則越來越多且變化頻繁,此時研發(fā)側能否快速交付就變得很重要。通過可視化編排,不用依賴代碼改造和版本發(fā)布,就可以快速調整業(yè)務流程和新增一套完整的新流程。當然,這也需要有很多相應的機制來保證穩(wěn)定性,畢竟代碼變更是每次都經過一個迭代的測試才能發(fā)布,這種動態(tài)變更的也需要有相應的灰度機制才行。
5.3 擴大業(yè)務身份的使用范圍
業(yè)務身份目前只在賣家發(fā)貨場景落地,在履約這邊有其他很多平臺化的能力,如何用平臺化的能力去支撐上層多變的業(yè)務是核心訴求。一旦業(yè)務身份確定,那么在整個履約鏈路中,都可以基于業(yè)務身份來做整體的流程編排,做差異化的處理。