內容來源:2017 年 12 月 2 日,餓了麼研發總監石佳寧在「IAS2017互聯網架構峯會」進行《餓了麼交易系統應用架構演進》演講分享。IT 大咖說(微信id:itdakashuo)做爲獨家視頻合做方,經主辦方和講者審閱受權發佈。緩存
閱讀字數:3176 | 8分鐘閱讀微信
業務系統的演進主要取決於業務場景,業務場景的定義和認知是隨着公司發展而造成的,基本上有着必定體量的大公司技術架構都相對穩定,業務架構則主要是對業務發展產生影響,好的業務架構可以保證業務更好的發展。本次嘉賓將會爲你們分享餓了麼業務架構的演進之路。架構
在講當前形態前首先要介紹下幾個基本概念。目前咱們的全部業務系統都是嚴格按照領域作劃分和組成的,開發人員須要知道領域、鏈路和服務這幾個概念間的關係和定義,一旦可以明確這些概念定義就可以容易明白業務和系統之間的關係以及系統和系統之間在職責上聯繫。併發
在餓了麼內部交易領域是相對大的範疇,是整個公司最重要的生命鏈路,所覆蓋的內容也並不是是集中式的,而是分散在各個系統的職責上。好比客服系統看似和交易無關,但其實有交易職責的,由於它最終會影響到交易的結果。高併發
所以咱們定義從用戶下單開始一直到訂單完成爲止,直接影響到最後訂單結果的內容都承載着交易的職責。性能
交易鏈路是完成一筆交易所須要的最短路徑,這其中的任意節點都是不可缺失的,一旦缺乏某一節點交易就沒法達成。一個大的領域每每會有不少條業務鏈路,通常會有一條是最關鍵的,其他幾條則是業務高點。設計
交易系統相對就比較好理解了,全部的服務以必定的業務爲邊界具體組成的明確部分就是交易系統。3d
上圖展現了參與交易的主要系統,能夠看到除開訂單和支付系統以外,還有不少影響交易結果但不承載完整交易職責的系統也在其中,整個交互關係很是複雜。正由於一個交易領域做爲交易系統的複雜要求,因此交易系統自己的職責是很容易混亂的。orm
爲了更清晰的肯定交易職責,咱們以交易訂單爲基礎拆分出了正向鏈路和逆向鏈路兩個部分。cdn
上圖是正向鏈路結構圖,能夠清晰的看到從用戶下單、支付成功、系統確認到最後接單完成的整個過程實際上是很是簡單的一個鏈路。
實際應用中也會將這個鏈路作的很是簡單,由於定義正向鏈路所承載的主要職責是讓一筆交易在技術和數據層面無缺無損的走到最後。
這套服務的系統要求是在系統自己IO、數據的可靠以及穩定性上,一些複雜的業務邏輯不會放到正向鏈路中。正向鏈路要保證的是在大流量高併發狀況下可以處理的很好並完成天天千萬級別調用。
上圖所示的是逆向鏈路,它多出來了仲裁和交易取消申請等環節,逆向鏈路實際上是以全部異常場景處理爲核心職責的。它的定義與正向鏈路恰好相反,正向鏈路重的是系統自己的可靠和性能,逆向鏈路重的是全部複雜場景的處理。
咱們在全部正常業務的處理過程當中,尤爲是新增的業務上必定會考慮逆向鏈路的支持。
這套服務架構大概分爲三層,最底層爲通用服務,這一層在交易領域內的職能和服務能力是應該被大範圍複用的。
中間爲核心服務層,是全部邏輯的承載,這一層分爲交易支撐和交易保障兩部分,這樣的劃分和前面提到的鏈路實際上是類似的,交易支撐承載的是流程職責,而一些業務場景會被單獨剝離出來放在交易保障中。
最上層是對接的業務系統,幾乎因此涉及到的交易系統都會對接底層的服務。
以這套架構爲核心就會發現有大一部分是可以存下來或者是能夠複用的。
咱們的整個交易服務是比較垂直的,它的核心是流程,由於交易其實就是流程不停遞歸的過程。
整個系統架構的組件並不複雜,主要是Redis和MySQL。經過MySQL進行解耦,以防與其餘系統有過多的交互。
在討論問題以前,首先分享給你們咱們團隊內部一直在說的一句話。
▶架構層面的一切努力都是爲了知足業務的擴展性須要
作業務架構實際上是比較務虛的一件事,不像作組件或者中間件的架構那樣有着明確的目標。業務需求的時刻改變使得業務架構的方案存在多種可能,結構人員須要在這些方案中選擇出對的那個,那麼怎麼纔算是對的方案呢?
咱們內部的評價標準是看這個架構可以使用多久,將來的兩到三個月是否會消退掉。
這裏將咱們在整個架構演進過程當中遇到的問題先列舉出來。
- 原系統職責龐大,維護和迭代成本很高,須要拆分。可是不知道怎麼拆,也很難對怎麼拆達成一致。
- 業務愈來愈複雜,接口和字段越加越多
- 新業務對老業務會形成衝擊,兼容永遠是考驗功力的
- 系統穩定性要求高,不論是新業務上線、老業務迭代、技術改造等,都不容許宕機哪怕一秒。
訂單與物流的交互服務能夠說是一個通用的案例,訂單服務承載外賣的交易,配送的運營由運單服務負責。
餓了麼的交易和物流是兩個大的系統,由兩個團隊分別負責。爲了在這兩大致系間創建方便的對接,咱們設想了一個訂單運單交互服務,讓訂單交易和物流之間的數據交互都經過它作中轉。最終咱們實現了這樣的一個服務,而且把必定的職能從訂單服務和運單服務拆分出來。
在實現的過程當中咱們遇到了新的問題,首先這個交互服務出於性能和數據便攜的考慮緩存了一部分的訂單或運單的數據直接從接口輸出。這樣的話交易鏈路上就多了一個掌握數據的節點,一旦整個鏈路出現數據不一致或者其餘問題,排查起來會至關困難。同時其餘各個服務的接入方沒法判斷接口或邏輯的提供方,須要花費大量的時間溝通。
後來咱們發現實現這套服務後整個開發效率反而更低了,最後咱們仍是將交互復的職責還回訂單服務和運單服務。
這讓咱們意識到若是一個領域或系統的職責是清晰並獨立的,那麼就應該讓它直接被其餘各個系統使用。另外對於系統的拆分和領域的識別要有共識,這個共識不只僅是交互的雙方。
在購買餓了麼會員時生成的實際上是一個虛擬訂單,當咱們開始接收到相似這樣的業務需求的時候是有一點糾結的,由於原有的外賣訂單流程有部分是支持該業務的,只不過須要在此基礎上作一些兼容,因此當時咱們所面臨着在創建一套新的系統和在原有系統上作兼容之間作出選擇。
最後咱們選擇新增虛擬訂單服務,由業務形態以及當前邏輯的可複用程度決定,儘可能服用,拆分(解耦)永遠比合並(內聚)容易
基於以上所提到的案例,這裏作一個總體的建議。
- 必定要有一張完整全面的架構圖,以系統的維度標註出核心主鏈路,確保其始終清晰。
- 花時間去了解業務和它的發展,爲將來作準備而不是直接作將來。
- 架構債務比代碼債務更難還,評審checklist以及債務總結必不可少。
業務系統的發展每每緊隨業務複雜度,可是這裏有一個悖論,即若是業務都不知道如何發展,那麼業務系統就更別談發展了。
對此咱們有一些思考和實踐,主要是在效率和效能方面。效率其實很好理解,就是如何改進架構使得更快的知足業務前進。效能則是在原先系統業務的能力上進行擴展。這二者並不是互相違背而是統一協調的,一個好的設計效率提升的同時效能也會隨之提升。
基於這樣的思考,咱們在內部作了一個嘗試,把咱們對交易的理解付諸到一套系統上。交易無外乎幾個形態,物品的交換、信息的交換和能力的交換,每每O2O或電商涉及到的都是相似能力的交換。
上圖就是這套系統的整個架構。最上層是導購前臺服務,負責與用戶的直接交互,是全部數據的入口。中間的交易中臺服務核心是合同的管理以及流程和能力的服務。最低層是全部的基礎支撐服務,店鋪、商品、帳戶這些資源都是基礎服務是交易數據的一部分,基於它們就會產生交易能力而後提供給前臺業務。