交易中臺架構(gòu)設(shè)計:海量并發(fā)高擴展,新業(yè)務(wù)秒級接入
本文根據(jù)孫玄老師在〖deeplus直播第219期〗線上分享演講內(nèi)容整理而成。
孫玄
奈學教育CEO
10年技術(shù)老兵,擅長系統(tǒng)架構(gòu)設(shè)計、大數(shù)據(jù)、運維、機器學習、技術(shù)管理等領(lǐng)域;
曾供職于百度、58集團、轉(zhuǎn)轉(zhuǎn)等公司。
大家好,今天我將從以下這三方面,來和大家分享一些海量高并發(fā)的經(jīng)驗:
中臺模式和微服務(wù)架構(gòu)到底有什么樣的關(guān)系
海量并發(fā)的業(yè)務(wù)中臺架構(gòu)如何設(shè)計與實踐
秒級新業(yè)務(wù)接入的交易中臺如何設(shè)計和實踐
一、中臺模式與微服務(wù)架構(gòu)的關(guān)系
現(xiàn)在大家應(yīng)該都知道,中臺最早是由芬蘭一家著名的游戲公司Supercell提出的,以小前臺的模式來組織若干個開發(fā)團隊。
也就是說,你的每個前臺的開發(fā)團隊,只需要了解開發(fā)一個業(yè)務(wù)/一個游戲所需要的業(yè)務(wù)邏輯就行。這樣的話,像每個業(yè)務(wù)會需要一些公共的東西,比如說像游戲引擎、一些內(nèi)部的開發(fā)工具、基礎(chǔ)設(shè)施等等,就不需要花時間去關(guān)注,會有一些專門的“部落”,也就是中臺部門來負責提供?!安柯洹笨梢愿鶕?jù)需要擴展為多個小分隊,每個小分隊都保持共同的目標,“部落”本身并不會提供游戲給消費者。
怎么理解呢?
首先我們都知道公司里面會分為多個前臺,每個前臺需要寫自己的業(yè)務(wù)邏輯,這個業(yè)務(wù)邏輯的底層是一個公共的東西,比如說你的游戲引擎、內(nèi)部的開發(fā)工具、平臺、基礎(chǔ)設(shè)施等等。
那什么是中臺?這些游戲引擎、內(nèi)部的開發(fā)工具、平臺、基礎(chǔ)設(shè)施等等就屬于中臺。
那什么是前臺?你的每個產(chǎn)品其實就是一個前臺,或者說,你每一個產(chǎn)品需要的業(yè)務(wù)模式就是前臺。
這種中臺模式在業(yè)界漸漸流行了起來,在2015年的時候,阿里巴巴張勇(逍遙子)宣布啟動中臺戰(zhàn)略,構(gòu)建符合數(shù)據(jù)技術(shù)時代,更具備創(chuàng)新性和靈活性的“大中臺、小前臺”的組織機制和業(yè)務(wù)機制,實現(xiàn)管理模式創(chuàng)新。
這時候是想做一個什么事情呢?其實阿里巴巴想做的一件事情就是把一些產(chǎn)品的技術(shù)力量、數(shù)據(jù)運營力量從前臺剝離出來,成為獨立的中臺。這個中臺就包括了像搜索事業(yè)部、共享業(yè)務(wù)事業(yè)部、數(shù)據(jù)平臺事業(yè)部等,為前臺即零售電商事業(yè)群提供服務(wù)。
也就是說,中臺總共包含了這樣的四部分:
搜索事業(yè)部,做的是算法中臺。其實從名字來看,搜索事業(yè)部更多是在搞搜索,搜索中主要的兩件事一個是召回,一個是排序。所以搜索事業(yè)部在做的事情其實就是算法相關(guān)的一些事情,會偏多一些;
共享業(yè)務(wù)事業(yè)部,做的是業(yè)務(wù)中臺,包括比如交易中心、商品中心、用戶中心……;
數(shù)據(jù)平臺事業(yè)部,圍繞數(shù)據(jù),也就是做數(shù)據(jù)中臺;
另外它還會涉及到一塊兒技術(shù)相關(guān)的(技術(shù)中臺),比如存儲、開發(fā)的整個框架等等。
那么今天我重點想講的是業(yè)務(wù)中臺,一個業(yè)務(wù)中臺到底包含哪些東西,這個對我們也是比較重要的一部分。要考慮的是怎么樣讓你的業(yè)務(wù)支撐的更加快一些。
業(yè)務(wù)中臺在我看來更多是一種從公司層面的組織架構(gòu),或者說業(yè)務(wù)架構(gòu)。我們將業(yè)務(wù)中臺抽象出來,既然它是一種業(yè)務(wù)架構(gòu)和組織架構(gòu)的結(jié)合體,那么我該怎樣實現(xiàn)它呢?
實現(xiàn)的時候,我可以采用微服務(wù)架構(gòu),也可以采用單體架構(gòu),還可以采用SOA架構(gòu),還可以采用數(shù)據(jù)架構(gòu)。
所以大家想一下,業(yè)務(wù)中臺也好,技術(shù)中臺也好,它想要承擔的責任是什么呢?業(yè)務(wù)中臺在實現(xiàn)過程中可以采用微服務(wù)架構(gòu),就僅此而已嗎?
在我看來,微服務(wù)架構(gòu)其實僅僅是中臺模式落地的一種典型技術(shù)架構(gòu)實現(xiàn)方式。這一點大家一定要記住。
理解了這點之后,就不會把整個的微服務(wù)架構(gòu)和整個的業(yè)務(wù)中臺混為一談了。這也是實際過程中比較重要的一部分,我覺得也比較重要。
接下來,也就是本次分享的第二部分,我們來分析一下,業(yè)務(wù)中臺在實現(xiàn)微服務(wù)架構(gòu)的時候,應(yīng)該怎么做?
二、海量并發(fā)的業(yè)務(wù)中臺架構(gòu)
如何設(shè)計與實踐
大家可以想一下,假如你要做一個交易業(yè)務(wù)中臺,或者打算做一個電商業(yè)務(wù),業(yè)務(wù)里面一個請求過來,比如說發(fā)布一個商品,到了你的服務(wù)端,你要構(gòu)建你服務(wù)的一套架構(gòu),要怎樣構(gòu)建呢?
首先業(yè)務(wù)過來,一定要有一個接入,負責接入這個請求。接入請求是為了做什么呢?比如可能是負責和前端的一個連接,連接后,要對請求做一些處理,比如說對它做一些請求鑒權(quán)、通用參數(shù)的檢查、路由的轉(zhuǎn)發(fā)等等,這些東西總得有一個服務(wù)來做,這個服務(wù)我們就叫做網(wǎng)關(guān)層。
圖1
網(wǎng)關(guān)層并不負責處理具體的業(yè)務(wù)邏輯。比如說你發(fā)布商品的時候,一定會有一個具體的業(yè)務(wù)邏輯,這個業(yè)務(wù)邏輯是誰來處理呢?當然是交給下一層——業(yè)務(wù)邏輯層。
業(yè)務(wù)邏輯層里就是對你業(yè)務(wù)的一個數(shù)據(jù)的處理。舉個例子,比如說我們整個的業(yè)務(wù)邏輯層包含什么東西呢?你使用微信,給你好久沒有聯(lián)系的一個朋友發(fā)了一條消息:“哥們兒,今天有空嗎?我們約個飯”
當你發(fā)出去后,微信告訴你信息已發(fā)送,但被對方拒收。說明什么?說明你被對方拉黑了。在座的各位都有過這種經(jīng)歷吧?沒有的話,你的人生是不完整的,哈哈。
那這種情況下,他拉黑的處理,對我們來說就是一個業(yè)務(wù)邏輯的處理。這個業(yè)務(wù)邏輯處理,包含“拉黑”這個操作,包括不管你是發(fā)消息,還是聊天、轉(zhuǎn)賬,都需要這樣的一個模塊。既然是一個模塊,我們就把他抽出來,變成了一個業(yè)務(wù)公共的邏輯層。
所以我們邏輯層一般來說會分為兩部分,一部分是個性化的業(yè)務(wù),另一部分是公共的業(yè)務(wù)。比如“拉黑”這種操作,就是公共的。但不管是公共的業(yè)務(wù)邏輯,還是個性化的業(yè)務(wù)邏輯,都需要訪問數(shù)據(jù)。所以接下來的一層就是數(shù)據(jù)訪問層(見圖1)。
數(shù)據(jù)訪問層很顯然,就是提供底層數(shù)據(jù)庫的一個增刪改查;以及當數(shù)據(jù)量比較大的時候,要能夠做到分庫分表,做一個Sharding的工作;以及要做到屏蔽底層數(shù)據(jù)存儲差異性。
再往下就是DB和Cache。
那么,在這個架構(gòu)里面,大家想想看,我們整個的業(yè)務(wù)邏輯層包含了哪些部分呢?
圖2
所謂中臺,其實就是哪些東西是公共的,是不變的。
那很顯然,網(wǎng)關(guān)是不變的;業(yè)務(wù)邏輯層是變化的,但業(yè)務(wù)邏輯層里中臺的部分,是不變化的;數(shù)據(jù)訪問層也是公共的;包括底層的db,不屬于業(yè)務(wù)范疇,其實是一個技術(shù)的支撐,我們叫技術(shù)中臺。
所以在這個架構(gòu)里面,我們就會看到:
網(wǎng)關(guān)層屬于業(yè)務(wù)中臺;
公共的業(yè)務(wù)邏輯層屬于業(yè)務(wù)中臺;
數(shù)據(jù)訪問層屬于業(yè)務(wù)中臺;
個性化業(yè)務(wù)邏輯層屬于業(yè)務(wù)前臺;
底層DB屬于技術(shù)中臺;
注冊中心,已有的配置中心,也可以劃入技術(shù)中臺的范疇。
所以我們就會看到,實際上當你將整個的業(yè)務(wù)按照微服務(wù)這樣來落地的時候,網(wǎng)關(guān)層、公共業(yè)務(wù)邏輯層、數(shù)據(jù)訪問層這些都屬于中臺范疇;個性化的業(yè)務(wù)邏輯層屬于前臺范疇。大家一定要搞清楚。
搞清楚之后,我們做中臺就比較簡單了,也就是說,取決于能不能在業(yè)務(wù)層面將公共能力下沉為服務(wù),并做好服務(wù)連接。
怎么理解呢?
比如說,像網(wǎng)關(guān)層、公共的業(yè)務(wù)邏輯層等,你應(yīng)該把它抽象出來,做為一個獨立的服務(wù)來執(zhí)行。這是我們在整體的思路上需要去沉淀的。
那么下沉為服務(wù)后,服務(wù)連接要怎么去做呢?我們接下來花點時間講講這塊兒。
比如轉(zhuǎn)轉(zhuǎn),里面有些怎樣的業(yè)務(wù)呢?因為它是轉(zhuǎn)賣的二手商品,所以就會有C2C(個人對個人)、B2C(商家對個人)、C2B(個人對商家)各種不同的商品模式,會有很多不同的業(yè)務(wù)。
圖3
在這些業(yè)務(wù)里面,不論是C2C、B2C還是C2B,這幾種業(yè)務(wù)模式里面都一定會有些公共的業(yè)務(wù)邏輯,也一定會有個性化的部分。個性化的東西,比如你是C2C的,有C2C的業(yè)務(wù)邏輯層;B2C的,有B2C的業(yè)務(wù)邏輯層;C2B的有C2B的業(yè)務(wù)邏輯層,那么這時我們在沉淀中臺的時候,就將公共的東西抽出來,變成我們的業(yè)務(wù)中臺,這個是我們實際過程中在做的一個事兒。
剛才說到了,我們在實現(xiàn)中臺架構(gòu)的時候,其實就是實現(xiàn)了微服務(wù)架構(gòu),里面網(wǎng)關(guān)、公共邏輯層、數(shù)據(jù)訪問層屬于業(yè)務(wù)中臺。但是業(yè)務(wù)邏輯層,很顯然,它是個性化的,屬于小前臺。我們重點聚焦的就是業(yè)務(wù)中臺的范疇可以怎么去做,也就是將公共能力下沉為服務(wù)。
圖4
另外一塊,業(yè)務(wù)中臺可能會有很多,比如說商品、交易、搜索、推薦……確實,如果我的前臺業(yè)務(wù),比如說新做了一個業(yè)務(wù)線,怎樣才能讓它一鍵接入呢?這個對我們來說也是一個比較有意思的事情。
大家可以看這個圖,一起想想看:
圖5
圖中右邊部分,使我們整個的一個中臺,比如說商品中心、用戶中心、交易中心、搜索中心等等,還有很多的一些其他的事情,也可以去做。在這種情況下,有這么多的中臺需要接入,當我如果真的需要接入一個小前臺的時候,難道這些中心我都要一個一個接入嗎?
很顯然,對我們來說太麻煩了。我們希望怎樣?
我們希望,一個業(yè)務(wù),首先能夠給我分配一個ID,比如是1,就將這個業(yè)務(wù)注冊為業(yè)務(wù)中心的1號,注冊完后,接下來我對這個業(yè)務(wù)的標識就都會通過這個ID來做。當然這個ID有可能是一個ID,也有可能是一個三級ID。比如說一級類,二級類,三級類……
那在這種情況下,大家可以想一個問題:你現(xiàn)在已經(jīng)對這個業(yè)務(wù)做好一個標識了,那接下來這個業(yè)務(wù)需要哪些中臺的能力呢?
你需要做什么?你需要做一個配置。
那這個配置配的是什么呢?
舉個例子,就是把你這個業(yè)務(wù)需要的中臺,比如要接入商品中心、搜索中心,接下來要做的的事情就是把ID和搜索中心構(gòu)建起來就好了,你需要在配置中心里配置一下你前臺所需要接入的中臺。
配置完以后會有一個接入策略,也就是以什么方式進行接入,比方說商品要接入到搜索,需要告訴我搜索在接入時要提供哪些字段可建索引、哪些字段不能建索引。首先對業(yè)務(wù)進行標識以后,業(yè)務(wù)要接入哪些中臺需要有個配置,配置完后業(yè)務(wù)要怎么接入需要有個接入策略,這樣當我要發(fā)布一個商品的時候,把商品推到搜索中心,搜索中心拿到商品后按照配置規(guī)則就會知道哪些字段可建索引、哪些字段不可建索引,最終把整個事情構(gòu)建起來。因此構(gòu)建這樣一套接入體系很重要。
三、秒級新業(yè)務(wù)接入的交易中臺
如何設(shè)計與實踐
要構(gòu)建一個中臺,首先要做一個微服務(wù)架構(gòu),把微服務(wù)架構(gòu)里的網(wǎng)關(guān)、公用業(yè)務(wù)邏輯、訪問順序做成中臺,把個性化的部分做成業(yè)務(wù)邏輯層這個小前臺,然后接入的時候把整個業(yè)務(wù)通過這種方式進行接入。
那么,秒級新業(yè)務(wù)的接入我們應(yīng)該怎么做呢?
圖6
大家可以從上圖看到,在很多情況下訂單的整個流程是比較復雜的,電商訂單的狀態(tài)持續(xù)變化,每個狀態(tài)的邏輯關(guān)聯(lián)關(guān)系在不同的狀態(tài)里變化都是不一樣的。比如說退款這個操作,在發(fā)貨前和發(fā)貨后是完全不同的流程,發(fā)貨前申請退款就會馬上給予退款,但在已發(fā)貨的狀態(tài)下申請退款,就需要看商家是否同意,同意則退款完成,不同意則會駁回。
圖7
在很多情況下,同一個業(yè)務(wù)或者兩個不同的業(yè)務(wù),它們80%的業(yè)務(wù)流程都是一樣的,只有20%不同,如果每一個不同的場景全都通過硬編碼的方式來做,那整個業(yè)務(wù)的復雜度就會比較高。大家可以對比看看上圖中C2C交易與自營交易的流程。
圖8
如果是在業(yè)務(wù)初創(chuàng)期,可以用硬編碼就行,硬編碼就是同一個狀態(tài)它在滿足不同流程里的繼續(xù)往下不同的流轉(zhuǎn),你就可以if else。比如說if這個時間等于1干什么事情,else if這個時間等于2干什么事情。這時如果你的狀態(tài)不復雜的情況下,這個事情做起來是比較簡單的。但如果狀態(tài)比較復雜的情況下用硬編碼,基本上你就廢了,那這種情況下怎么做呢?
這時無非就是要做什么事情?從一個初始狀態(tài)到目標狀態(tài),你給它一個動作以后讓它進行流轉(zhuǎn),就是在有限狀態(tài)以及在狀態(tài)之間的一個轉(zhuǎn)移的數(shù)據(jù)模型,也就是狀態(tài)和動作之間的轉(zhuǎn)移。什么是動作和轉(zhuǎn)移?可以看回圖6的例子,已支付是一個初始狀態(tài),申請退款是一個動作,然后它就進入了退款這個目標狀態(tài)。其實所有狀態(tài)之間的轉(zhuǎn)移,都可以用圖8說的FSM狀態(tài)機來表達。
圖9
這個FSM解決方案的作用是,怎樣在動作的加持下進行狀態(tài)的流轉(zhuǎn),之后我們就可以對狀態(tài)機進行抽象。那么狀態(tài)機包含哪些要素?
圖10
首先要定義狀態(tài)機的框架,抽象業(yè)務(wù)場景狀態(tài)的角色,包括初識狀態(tài)、目標狀態(tài),還有角色及角色不同的操作權(quán)限,以及操作對應(yīng)的事件、事件操作相應(yīng)的Action實現(xiàn)(Handler)。需要展開說明一下的是事件的定義,就是角色A在初始狀態(tài)S1下,執(zhí)行OP1操作,將使用Handler來處理業(yè)務(wù)邏輯,執(zhí)行成功將狀態(tài)設(shè)置為目標狀態(tài)S2。這些就是交易中臺FSM普適的架構(gòu)設(shè)計和實踐。
圖11
如果要用一些結(jié)構(gòu)化來描述應(yīng)該怎么描述呢?FSM落地其實無非就是狀態(tài)轉(zhuǎn)移表的定義,狀態(tài)轉(zhuǎn)移表里包含操作、角色、初始狀態(tài)、目標狀態(tài)、Handler這幾個因素,只要構(gòu)建起這個狀態(tài)轉(zhuǎn)移表,其他就好辦了。如果你用Java語言,那這套框架可以基于Spring State Machine來做。
假設(shè)現(xiàn)在有了這套狀態(tài)轉(zhuǎn)移表,或者說是整個通用的FSM框架表,那么要接入新事件的話需要做什么事情?首先是要配置好這個表,然后進行新Handler業(yè)務(wù)處理的編寫,這樣就能很快進行接入。如果你沒有新的Handler,那整個接入就是秒級的,如果有新的Handler需要做的話,寫幾行代碼就可以了,所以說這套東西對于我們來說整個處理是非??斓?。
圖12
如果我們有了這套FSM狀態(tài)機,這時再去接入不同的業(yè)務(wù),無非就是在數(shù)據(jù)庫里配置一下,寫一些配置表就好了。也就是說通過中臺FSM能力,只要將狀態(tài)圖繪制出來,相應(yīng)的狀態(tài)流轉(zhuǎn)表配置就已經(jīng)產(chǎn)生。然后Handler只需要關(guān)注當前操作的業(yè)務(wù)邏輯就行,極大地解耦狀態(tài)和業(yè)務(wù)。這套FSM在早期的百度和58都很好地滿足了業(yè)務(wù)場景。
Q & A
Q1:為什么不用MySQL做分庫分表?
A:分庫分表用MySQL還是可以的,但畢竟你的數(shù)據(jù)訪問層還是要關(guān)注分庫分表這個動作,這個時候業(yè)務(wù)開發(fā)起來工作量就比較大,所以最好的方式是你的業(yè)務(wù)同學不需要關(guān)注分庫分表,把分庫分表的東西下沉到DB層,讓DB層直接來做就好。另外,分表還會帶來很多問題,比如查詢有多維度的情況下,其實不是很好分表,分表后反而會帶來很多問題。
Q2:互聯(lián)網(wǎng)app類的架構(gòu)能大概講一下嗎?
A:微服務(wù)架構(gòu)包含網(wǎng)關(guān)層、業(yè)務(wù)邏輯層、數(shù)據(jù)訪問層以及DB,其實這就是一個APP的后臺架構(gòu),目前基本都采用微服務(wù)架構(gòu)來做,但有些公司是業(yè)務(wù)邏輯層和數(shù)據(jù)訪問層合在一起的,我個人是建議分開。
Q3:請問狀態(tài)機機制有什么缺點?
A:我覺得缺點只有一個,就是開發(fā)成本比較高,但一旦開發(fā)出來之后,只要配置就好了,整個靈活性很高。
Q4:訂單屬于交易領(lǐng)域嗎?
A:是的,屬于交易的子領(lǐng)域,但是訂單和交易要分成兩個不同的服務(wù),因為它們屬于一個大的領(lǐng)域,但不同的子領(lǐng)域,訂單是一個服務(wù),交易是一個服務(wù),還有清算、結(jié)算也是一個服務(wù)。
Q5:你們的中臺系統(tǒng)都是多IDC的嗎?
A:我們原來是多機房的,有兩個機房,北京一個,天津一個,在這種情況下我們的整個中臺其實是兩個機房的。
Q6:能介紹一下您對中臺的理解嗎?
A:中臺本身就是把一些公共的東西做一個抽象,比如把業(yè)務(wù)的東西抽象出來那它就是一個中臺,然后用中臺來服務(wù)不同的業(yè)務(wù)。
Q7:你們用Redis都存儲什么數(shù)據(jù)?用哨兵還是cluster?
A:用Redis存我們的緩存數(shù)據(jù)。目前主要是用cluster模式,如果量小的話可以用Redis的主從模式,通過哨兵機制來做,但如果是比較成型的還是推薦用cluster模式來做。
Q8:ui層的網(wǎng)關(guān)用kong么?
A:不是,推薦大家用zuul。
Q9:狀態(tài)機有決策表嗎?決策樹是否都能達到目的?
A:這個不需要,因為它其實現(xiàn)在這個還不涉及到智能決策問題,本質(zhì)上就是流程都是確定的一個狀態(tài),確定的東西其實沒必要引入一些智能的角色,直接把需要流轉(zhuǎn)的東西配置在狀態(tài)表里就好。
Q10:spring cloud gateway上生產(chǎn)如何?
A:還不是非常成熟,不建議直接上生產(chǎn)。
Q11:一個微服務(wù)都要對應(yīng)單獨的一個庫嗎?
A:不一定,有可能會存在多個微服務(wù)對應(yīng)一個DB,還是要看你業(yè)務(wù)本身的設(shè)計,沒必要為了對應(yīng)而對應(yīng)。
Q12:docker swarm的overlay網(wǎng)絡(luò)是不是慢?用什么網(wǎng)絡(luò)好?
A:docker本身沒問題,但swarm用得比較少,我建議你直接用k8s就好了。
Q13:k8s和docker的關(guān)系?
A:docker本身是一個容器,目的是讓你方便擴容。想想看當你有很多個容器的時候,每個容器的生命周期、重啟、遷移等,總得有個地方去管理,而k8s就是對docker進行管理的系統(tǒng)。
Q14:您是怎么快速構(gòu)建知識體系的?
A:很多同學學習了半天,學習了很多知識點,但光有知識點是沒用的,因為無論你最終做一個架構(gòu)師也好、工程師也好,你都需要具備架構(gòu)設(shè)計的能力,也就是當你面對一個業(yè)務(wù)場景,能不能給出一個迎刃而解的方案,這種光有很多知識點是沒用的,要由點連成線,由線成面。那這個過程需要干什么呢?我覺得最主要是通過深度思考來把這些知識點關(guān)聯(lián)起來,這個東西其實很難的,最好的方式就是跟著大牛,讓他帶著你去做。
Q15:老師的職業(yè)路線很好,能講一下您每段職業(yè)當時的想法嗎?
A:第一是內(nèi)驅(qū)力,就是對自己的職業(yè)定位,你想成為什么樣的人?這可以說是拉開人與人之間距離的核心發(fā)動機;第二是深度思考能力,就是能不能透過現(xiàn)象看出本質(zhì)問題,這個能力非常重要;第三是技術(shù)視野,就是要把你的眼界打開。
特別推薦一個分享架構(gòu)+算法的優(yōu)質(zhì)內(nèi)容,還沒關(guān)注的小伙伴,可以長按關(guān)注一下:
長按訂閱更多精彩▼
如有收獲,點個在看,誠摯感謝
免責聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!