饿了么交易系统应用架构演进
內(nèi)容來源:2017 年 12 月 2 日,餓了么研發(fā)總監(jiān)石佳寧在“IAS2017互聯(lián)網(wǎng)架構(gòu)峰會”進(jìn)行《餓了么交易系統(tǒng)應(yīng)用架構(gòu)演進(jìn)》演講分享。IT 大咖說(微信id:itdakashuo)作為獨家視頻合作方,經(jīng)主辦方和講者審閱授權(quán)發(fā)布。
閱讀字?jǐn)?shù):3176 | 8分鐘閱讀
嘉賓演講視頻及PPT回顧:suo.im/5qrxMT摘要
業(yè)務(wù)系統(tǒng)的演進(jìn)主要取決于業(yè)務(wù)場景,業(yè)務(wù)場景的定義和認(rèn)知是隨著公司發(fā)展而形成的,基本上有著一定體量的大公司技術(shù)架構(gòu)都相對穩(wěn)定,業(yè)務(wù)架構(gòu)則主要是對業(yè)務(wù)發(fā)展產(chǎn)生影響,好的業(yè)務(wù)架構(gòu)能夠保證業(yè)務(wù)更好的發(fā)展。本次嘉賓將會為大家分享餓了么業(yè)務(wù)架構(gòu)的演進(jìn)之路。
當(dāng)前形態(tài)
在講當(dāng)前形態(tài)前首先要介紹下幾個基本概念。目前我們的所有業(yè)務(wù)系統(tǒng)都是嚴(yán)格按照領(lǐng)域做劃分和組成的,開發(fā)人員需要知道領(lǐng)域、鏈路和服務(wù)這幾個概念間的關(guān)系和定義,一旦能夠明確這些概念定義就能夠容易明白業(yè)務(wù)和系統(tǒng)之間的關(guān)系以及系統(tǒng)和系統(tǒng)之間在職責(zé)上聯(lián)系。
交易領(lǐng)域
在餓了么內(nèi)部交易領(lǐng)域是相對大的范疇,是整個公司最重要的生命鏈路,所覆蓋的內(nèi)容也并非是集中式的,而是分散在各個系統(tǒng)的職責(zé)上。比如客服系統(tǒng)看似和交易無關(guān),但其實有交易職責(zé)的,因為它最終會影響到交易的結(jié)果。
因此我們定義從用戶下單開始一直到訂單完成為止,直接影響到最后訂單結(jié)果的內(nèi)容都承載著交易的職責(zé)。
交易鏈路
交易鏈路是完成一筆交易所需要的最短路徑,這其中的任意節(jié)點都是不可缺失的,一旦缺少某一節(jié)點交易就無法達(dá)成。一個大的領(lǐng)域往往會有很多條業(yè)務(wù)鏈路,一般會有一條是最關(guān)鍵的,其余幾條則是業(yè)務(wù)高點。
交易系統(tǒng)
交易系統(tǒng)相對就比較好理解了,所有的服務(wù)以一定的業(yè)務(wù)為邊界具體組成的明確部分就是交易系統(tǒng)。
上圖展示了參與交易的主要系統(tǒng),可以看到除開訂單和支付系統(tǒng)之外,還有很多影響交易結(jié)果但不承載完整交易職責(zé)的系統(tǒng)也在其中,整個交互關(guān)系非常復(fù)雜。正因為一個交易領(lǐng)域作為交易系統(tǒng)的復(fù)雜要求,所以交易系統(tǒng)本身的職責(zé)是很容易混亂的。
業(yè)務(wù)特性和基本劃分
為了更清晰的確定交易職責(zé),我們以交易訂單為基礎(chǔ)拆分出了正向鏈路和逆向鏈路兩個部分。
上圖是正向鏈路結(jié)構(gòu)圖,可以清晰的看到從用戶下單、支付成功、系統(tǒng)確認(rèn)到最后接單完成的整個過程其實是非常簡單的一個鏈路。
實際應(yīng)用中也會將這個鏈路做的非常簡單,因為定義正向鏈路所承載的主要職責(zé)是讓一筆交易在技術(shù)和數(shù)據(jù)層面完好無損的走到最后。
這套服務(wù)的系統(tǒng)要求是在系統(tǒng)本身IO、數(shù)據(jù)的可靠以及穩(wěn)定性上,一些復(fù)雜的業(yè)務(wù)邏輯不會放到正向鏈路中。正向鏈路要保證的是在大流量高并發(fā)情況下能夠處理的很好并完成每天千萬級別調(diào)用。
上圖所示的是逆向鏈路,它多出來了仲裁和交易取消申請等環(huán)節(jié),逆向鏈路其實是以所有異常場景處理為核心職責(zé)的。它的定義與正向鏈路剛好相反,正向鏈路重的是系統(tǒng)本身的可靠和性能,逆向鏈路重的是所有復(fù)雜場景的處理。
我們在所有正常業(yè)務(wù)的處理過程中,尤其是新增的業(yè)務(wù)上一定會考慮逆向鏈路的支持。
服務(wù)架構(gòu)
這套服務(wù)架構(gòu)大概分為三層,最底層為通用服務(wù),這一層在交易領(lǐng)域內(nèi)的職能和服務(wù)能力是應(yīng)該被大范圍復(fù)用的。
中間為核心服務(wù)層,是所有邏輯的承載,這一層分為交易支撐和交易保障兩部分,這樣的劃分和前面提到的鏈路其實是相似的,交易支撐承載的是流程職責(zé),而一些業(yè)務(wù)場景會被單獨剝離出來放在交易保障中。
最上層是對接的業(yè)務(wù)系統(tǒng),幾乎所以涉及到的交易系統(tǒng)都會對接底層的服務(wù)。
以這套架構(gòu)為核心就會發(fā)現(xiàn)有大一部分是能夠存下來或者是可以復(fù)用的。
系統(tǒng)架構(gòu)
我們的整個交易服務(wù)是比較垂直的,它的核心是流程,因為交易其實就是流程不停遞歸的過程。
整個系統(tǒng)架構(gòu)的組件并不復(fù)雜,主要是Redis和MySQL。通過MySQL進(jìn)行解耦,以防與其他系統(tǒng)有過多的交互。
當(dāng)時的問題
在討論問題之前,首先分享給大家我們團(tuán)隊內(nèi)部一直在說的一句話。
?架構(gòu)層面的一切努力都是為了滿足業(yè)務(wù)的擴展性需要
做業(yè)務(wù)架構(gòu)其實是比較務(wù)虛的一件事,不像做組件或者中間件的架構(gòu)那樣有著明確的目標(biāo)。業(yè)務(wù)需求的時刻改變使得業(yè)務(wù)架構(gòu)的方案存在多種可能,結(jié)構(gòu)人員需要在這些方案中選擇出對的那個,那么怎么才算是對的方案呢?
我們內(nèi)部的評價標(biāo)準(zhǔn)是看這個架構(gòu)能夠使用多久,未來的兩到三個月是否會消退掉。
遇到的難題
這里將我們在整個架構(gòu)演進(jìn)過程中遇到的問題先列舉出來。
- 原系統(tǒng)職責(zé)龐大,維護(hù)和迭代成本很高,需要拆分。但是不知道怎么拆,也很難對怎么拆達(dá)成一致。
- 業(yè)務(wù)越來越復(fù)雜,接口和字段越加越多
- 新業(yè)務(wù)對老業(yè)務(wù)會造成沖擊,兼容永遠(yuǎn)是考驗功力的
- 系統(tǒng)穩(wěn)定性要求高,不管是新業(yè)務(wù)上線、老業(yè)務(wù)迭代、技術(shù)改造等,都不允許宕機哪怕一秒。
案例-訂單與物流交互服務(wù)
訂單與物流的交互服務(wù)可以說是一個通用的案例,訂單服務(wù)承載外賣的交易,配送的運營由運單服務(wù)負(fù)責(zé)。
餓了么的交易和物流是兩個大的系統(tǒng),由兩個團(tuán)隊分別負(fù)責(zé)。為了在這兩大體系間建立方便的對接,我們設(shè)想了一個訂單運單交互服務(wù),讓訂單交易和物流之間的數(shù)據(jù)交互都通過它做中轉(zhuǎn)。最終我們實現(xiàn)了這樣的一個服務(wù),并且把一定的職能從訂單服務(wù)和運單服務(wù)拆分出來。
在實現(xiàn)的過程中我們遇到了新的問題,首先這個交互服務(wù)出于性能和數(shù)據(jù)便攜的考慮緩存了一部分的訂單或運單的數(shù)據(jù)直接從接口輸出。這樣的話交易鏈路上就多了一個掌握數(shù)據(jù)的節(jié)點,一旦整個鏈路出現(xiàn)數(shù)據(jù)不一致或者其他問題,排查起來會相當(dāng)困難。同時其他各個服務(wù)的接入方無法判斷接口或邏輯的提供方,需要花費大量的時間溝通。
后來我們發(fā)現(xiàn)實現(xiàn)這套服務(wù)后整個開發(fā)效率反而更低了,最后我們還是將交互復(fù)的職責(zé)還回訂單服務(wù)和運單服務(wù)。
這讓我們意識到如果一個領(lǐng)域或系統(tǒng)的職責(zé)是清晰并獨立的,那么就應(yīng)該讓它直接被其他各個系統(tǒng)使用。另外對于系統(tǒng)的拆分和領(lǐng)域的識別要有共識,這個共識不僅僅是交互的雙方。
案例-新業(yè)務(wù)的形態(tài)支持
在購買餓了么會員時生成的其實是一個虛擬訂單,當(dāng)我們開始接收到類似這樣的業(yè)務(wù)需求的時候是有一點糾結(jié)的,因為原有的外賣訂單流程有部分是支持該業(yè)務(wù)的,只不過需要在此基礎(chǔ)上做一些兼容,所以當(dāng)時我們所面臨著在建立一套新的系統(tǒng)和在原有系統(tǒng)上做兼容之間做出選擇。
最后我們選擇新增虛擬訂單服務(wù),由業(yè)務(wù)形態(tài)以及當(dāng)前邏輯的可復(fù)用程度決定,盡量服用,拆分(解耦)永遠(yuǎn)比合并(內(nèi)聚)容易
整體建議
基于以上所提到的案例,這里做一個整體的建議。
- 一定要有一張完整全面的架構(gòu)圖,以系統(tǒng)的維度標(biāo)注出核心主鏈路,確保其始終清晰。
- 花時間去了解業(yè)務(wù)和它的發(fā)展,為未來做準(zhǔn)備而不是直接做未來。
- 架構(gòu)債務(wù)比代碼債務(wù)更難還,評審checklist以及債務(wù)總結(jié)必不可少。
未來的發(fā)展
業(yè)務(wù)系統(tǒng)的發(fā)展往往緊隨業(yè)務(wù)復(fù)雜度,但是這里有一個悖論,即如果業(yè)務(wù)都不知道如何發(fā)展,那么業(yè)務(wù)系統(tǒng)就更別談發(fā)展了。
對此我們有一些思考和實踐,主要是在效率和效能方面。效率其實很好理解,就是如何改進(jìn)架構(gòu)使得更快的滿足業(yè)務(wù)前進(jìn)。效能則是在原先系統(tǒng)業(yè)務(wù)的能力上進(jìn)行擴展。這兩者并非互相違背而是統(tǒng)一協(xié)調(diào)的,一個好的設(shè)計效率提高的同時效能也會隨之提高。
基于這樣的思考,我們在內(nèi)部做了一個嘗試,把我們對交易的理解付諸到一套系統(tǒng)上。交易無外乎幾個形態(tài),物品的交換、信息的交換和能力的交換,往往O2O或電商涉及到的都是類似能力的交換。
上圖就是這套系統(tǒng)的整個架構(gòu)。最上層是導(dǎo)購前臺服務(wù),負(fù)責(zé)與用戶的直接交互,是所有數(shù)據(jù)的入口。中間的交易中臺服務(wù)核心是合同的管理以及流程和能力的服務(wù)。最低層是所有的基礎(chǔ)支撐服務(wù),店鋪、商品、賬戶這些資源都是基礎(chǔ)服務(wù)是交易數(shù)據(jù)的一部分,基于它們就會產(chǎn)生交易能力然后提供給前臺業(yè)務(wù)。
總結(jié)
以上是生活随笔為你收集整理的饿了么交易系统应用架构演进的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: GoJS超详细入门(插件使用无非:引包、
- 下一篇: Linux实现最常用的磁盘阵列--RAI