一个细节翔实、可供参考的支付体系架构演进实例--转
注:本文整理自美麗聯(lián)合集團(tuán)資深工程師陳宗在 ArchSummit 深圳 2017 上的演講,原題為:《支付體系架構(gòu)與實(shí)踐》。
上篇:支付體系架構(gòu)演進(jìn)
在過(guò)去 4 年的時(shí)間里,作為面向億級(jí)用戶(hù)的大型時(shí)尚消費(fèi)平臺(tái),美聯(lián)集團(tuán)歷經(jīng)著高速的業(yè)務(wù)增長(zhǎng)和快速的業(yè)務(wù)演進(jìn)。而其中最重要的基礎(chǔ)業(yè)務(wù)平臺(tái),美聯(lián)支付如何穩(wěn)打穩(wěn)扎、平滑演進(jìn),快速適應(yīng)并高效支持著業(yè)務(wù)的復(fù)雜變化。我們從單一功能到完整體系、從臃腫單體 Php 演變?yōu)楦咝阅芨呖煽靠缮炜s的分布式服務(wù)架構(gòu),于 16 年快速融合美麗說(shuō)和淘世界支付體系,并在歷年大促中保持無(wú)故障的出色表現(xiàn),逐漸摸索出適應(yīng)全集團(tuán)復(fù)雜業(yè)務(wù)形態(tài)和變化的支付平臺(tái)架構(gòu)。
支付系統(tǒng) 1.x
13 年下半年的時(shí)候,蘑菇街從導(dǎo)購(gòu)平臺(tái)轉(zhuǎn)為電商平臺(tái)。為了支撐電商業(yè)務(wù),我們快速實(shí)現(xiàn)了第一代的支付系統(tǒng)。當(dāng)時(shí)蘑菇街的業(yè)務(wù)簡(jiǎn)單、玩法單一。如圖 1.1 所示,第一代的支付系統(tǒng)只包含了支付最核心功能,從而盡快的支撐業(yè)務(wù)。在這期間,我們實(shí)現(xiàn)了面向業(yè)務(wù)的收銀臺(tái)、支付模塊,面向資金端的賬務(wù)模塊,以及與三方支付對(duì)接的渠道網(wǎng)關(guān)。
1.x 支付系統(tǒng)架構(gòu)
隨后的幾年,美聯(lián)的業(yè)務(wù)進(jìn)入超高速的發(fā)展,電商交易、以及支付的業(yè)務(wù)復(fù)雜度劇增,玩法多變。同時(shí),在經(jīng)歷數(shù)次大促之后,我們發(fā)現(xiàn),支付核心鏈路大促 QPS 峰值達(dá)到了日常的百倍以上。在這種情況下,我們其實(shí)遇到了蠻多的問(wèn)題,以下分為三部分來(lái)說(shuō)下我們當(dāng)時(shí)碰到的問(wèn)題:
?業(yè)務(wù)問(wèn)題
1.x 支付系統(tǒng)構(gòu)建的時(shí)候,支付系統(tǒng)設(shè)定了比如擔(dān)保交易、提現(xiàn)等支付交易表。但是隨著業(yè)務(wù)越來(lái)越復(fù)雜,我們加了越來(lái)越多的支付交易表,整個(gè)系統(tǒng)的架構(gòu)如同圖 1.2 所示的煙囪型架構(gòu)。當(dāng)時(shí)來(lái)一個(gè)業(yè)務(wù),我們加 1-N 張表。
煙囪型系統(tǒng)機(jī)構(gòu)
截止到 15 年底,整個(gè)支付系統(tǒng)存在這數(shù)十個(gè)支付交易表。這么多的表,側(cè)面反映了我們對(duì)支付業(yè)務(wù)并沒(méi)有做模型的抽象,只是在業(yè)務(wù)的野蠻生長(zhǎng)下,不斷的應(yīng)對(duì)和接入。同時(shí),在這種情況下,業(yè)務(wù)的邊界很模糊,經(jīng)常有業(yè)務(wù),一半的業(yè)務(wù)邏輯實(shí)現(xiàn)在業(yè)務(wù)方,一半的業(yè)務(wù)邏輯在支付方。
?系統(tǒng)問(wèn)題
當(dāng)時(shí)我們整一個(gè)支付系統(tǒng)都在一個(gè)巨大無(wú)比的單體 php 應(yīng)用里。雖然系統(tǒng)在演進(jìn),也分出了不少的模塊,但是大家知道。在一個(gè)巨大的單體應(yīng)用里,比較容易出現(xiàn)各模塊的耦合,比如支付模塊調(diào)用了渠道網(wǎng)關(guān)模塊的一個(gè)內(nèi)部的方法等等。而另外一個(gè),支付團(tuán)隊(duì)的幾十號(hào)同學(xué)每天都在一個(gè)應(yīng)用里面開(kāi)發(fā) & 發(fā)布。任何一個(gè)地方跪了,都有可能讓支付系統(tǒng)崩潰,穩(wěn)定性非常低。
最后,電商平臺(tái)的特性,決定了我們必須要不斷的提升支付系統(tǒng)的性能。在 15 年的時(shí)候,我們對(duì)支付系統(tǒng)的 DB 進(jìn)行了基于模塊的垂直拆分,如下圖所示。以用于提升系統(tǒng)容量。但這種情況下,我們還是碰到到性能瓶頸。
舉個(gè)例子:15 年雙十一,當(dāng)時(shí)定下來(lái)系統(tǒng)能夠支持 2kqps 的峰值支付性能。但在數(shù)輪鏈路壓測(cè)之后,即時(shí)我們對(duì) DB 進(jìn)行了垂直拆分,并用了最好硬件 fushion IO, 但是我們發(fā)現(xiàn)系統(tǒng)僅能支撐大概 1800qps 左右的支付。當(dāng)時(shí)其實(shí)是比較絕望的,我清楚的記得在 15 年的 10 月底,11 月初的很多白天黑夜,緊急對(duì)支付系統(tǒng)的擔(dān)保交易下單進(jìn)行了改造,添加了一系列的緩存,最終性能勉強(qiáng)能夠達(dá)標(biāo)。
支付系統(tǒng) DB 垂直拆分
?資金問(wèn)題
第一代的支付系統(tǒng)中,我們對(duì)各個(gè)業(yè)務(wù)方的支付接入,并未提供任何的授權(quán)和鑒權(quán)。也就是說(shuō)任何系統(tǒng)、任何團(tuán)隊(duì)都有可能調(diào)用支付系統(tǒng)接口進(jìn)行資金操作,當(dāng)時(shí)支付有一個(gè)萬(wàn)能的轉(zhuǎn)賬接口,業(yè)務(wù)方接入確實(shí)很方便,但其實(shí)埋了蠻多坑。雖然當(dāng)時(shí)我們支付的業(yè)務(wù)做了日志記錄,但是在數(shù)據(jù)庫(kù)里面,我們并未能區(qū)分來(lái)源的業(yè)務(wù)、哪種操作,導(dǎo)致了我們對(duì)各項(xiàng)業(yè)務(wù)的流水、收入、支出難以統(tǒng)計(jì)和核算。
另外我們當(dāng)時(shí)也碰到了數(shù)據(jù)一致性挑戰(zhàn)。當(dāng)時(shí)支付系統(tǒng)僅有內(nèi)外部渠道對(duì)賬,而對(duì)內(nèi)部的業(yè)務(wù)數(shù)據(jù),并沒(méi)有做好對(duì)賬事宜,經(jīng)常出現(xiàn)用戶(hù)反饋異常問(wèn)題,然后我們才能知曉。
支付體系 2.0 架構(gòu)實(shí)踐
1.x 的支付系統(tǒng)中,其實(shí)我們碰到了很多的問(wèn)題,痛定思痛,我們決心對(duì)支付體系做一次架構(gòu)升級(jí)。那么,怎么去做支付體系的架構(gòu)升級(jí)呢?,我們從兩個(gè)方面來(lái)進(jìn)行架構(gòu)升級(jí)梳理:
巨大的單體應(yīng)用必須得拆分,在拆分之前,我們需要確定業(yè)務(wù)、系統(tǒng)邊界,對(duì)支付業(yè)務(wù)進(jìn)行建模。
構(gòu)建完整的資金核算體系,以達(dá)到能夠清晰的知曉各類(lèi)業(yè)務(wù)的流水、收入、支出等。
拆分系統(tǒng)邊界
那么單體應(yīng)用拆分之前,那么如何確定邊界? 從三個(gè)維度對(duì)邊界進(jìn)行了拆分:
基于業(yè)務(wù),拆分為面向支付業(yè)務(wù),面向資金核算體系
基于場(chǎng)景,例如依據(jù)支付流程等
基于技術(shù)實(shí)現(xiàn),比如出于對(duì)系統(tǒng)的性能考慮等
我們對(duì)支付體系里面的核心系統(tǒng)拆分為:收銀臺(tái)、交易核心、支付核心、網(wǎng)關(guān)、賬務(wù)、會(huì)計(jì)、清算、合規(guī)等。下圖是對(duì)核心支付鏈路流程示意:
核心支付鏈路流程
支付體系 2.0 整體架構(gòu)
得益于蘑菇街強(qiáng)大的基礎(chǔ)平臺(tái) & 中間件系統(tǒng),比如 RPC 服務(wù)框架 Tesla,數(shù)據(jù)庫(kù)中間件 Raptor,可靠的消息中間件 Corgi,數(shù)據(jù)庫(kù)事件變更中間件 Pigeon,數(shù)據(jù)配置推送平臺(tái) metabase,分布式緩存 kvstore 等等。我們?cè)?15 年第四季度,對(duì)支付系統(tǒng)做了整體的服務(wù)化拆分。大家可以看下圖支付體系 2.0 的整體架構(gòu)圖:
支付體系 2.0 整體架構(gòu)圖
如圖所示,我們大致介紹下各系統(tǒng)的功能:
面向支付業(yè)務(wù)拆分為:收銀臺(tái)、交易核心、支付核心、渠道網(wǎng)關(guān)
面向資金核算拆分為:賬務(wù)、會(huì)計(jì)、清算、合規(guī)
其他基礎(chǔ)服務(wù),比如支付會(huì)員服務(wù),支付風(fēng)控和支付對(duì)賬等。
支付體系 2.0 系統(tǒng)拆分
上文中呈現(xiàn)了支付體系 2.0 的整體架構(gòu),我們接下來(lái)對(duì)各核心系統(tǒng)的拆分和實(shí)現(xiàn)進(jìn)行介紹:
?交易核心
從剛才的支付鏈路可以看出,交易核心作為支付系統(tǒng)入口,對(duì)接上層的業(yè)務(wù)系統(tǒng)。在 15 年底,支付系統(tǒng)有著數(shù)十張的支付交易表,如何抽取合適業(yè)務(wù)模型,是我們最重要的事情。另外,為了數(shù)據(jù)的統(tǒng)一性,我們對(duì)分散數(shù)十張的支付交易表進(jìn)行了多表聚合,以及訂單關(guān)聯(lián)。同時(shí),支付的接入管控也放在了交易核心實(shí)現(xiàn),整體的架構(gòu)如下圖所示:
交易核心架構(gòu)圖
基礎(chǔ)交易類(lèi)型抽象
交易核心里面如何做基礎(chǔ)交易類(lèi)型的模型抽象?主要還是基于對(duì)支付的理解,如圖 2.4 所示的例子中,電商交易的預(yù)售 和 廣告營(yíng)銷(xiāo)的購(gòu)買(mǎi),都是從用戶(hù)購(gòu)買(mǎi)直接到收款方。那么我們可以抽象為即時(shí)交易,即直接從 a 用戶(hù)到 b 用戶(hù)的支付行為。
基礎(chǔ)交易類(lèi)型抽象
基于對(duì)業(yè)務(wù)的分析理解,我們對(duì)交易核心的業(yè)務(wù)進(jìn)行了抽象,抽象為 10 多種交易類(lèi)型:
-
大家比較熟悉的:擔(dān)保交易、即時(shí)交易、充值、提現(xiàn)、擔(dān)保退款、即時(shí)退款、轉(zhuǎn)賬等。
-
以及不太常見(jiàn)的:提現(xiàn)退票、退款退單、異常退款、充值退款等。
多表聚合 & 訂單關(guān)聯(lián)
我們對(duì)數(shù)十張的支付交易表進(jìn)行多表聚合,是基于一張主表來(lái)實(shí)現(xiàn)。而在這種情況下,業(yè)務(wù)訂單如何保持唯一是我們需要考慮的事情。考慮到需要對(duì)上層業(yè)務(wù)的極少侵入性,在新設(shè)計(jì)的支付交易表中,有專(zhuān)門(mén)的字段用于做唯一鍵約束:
業(yè)務(wù)識(shí)別碼 + 業(yè)務(wù)訂單號(hào) 來(lái)進(jìn)行訂單唯一約束。
另外,做了一個(gè)小功能,任何訂單都可以追溯到初始單,如下圖為例,擔(dān)保交易下的所有的單子都可以找到,同時(shí)也能追溯到初始的訂單。
擔(dān)保交易訂單關(guān)聯(lián)
支付管控
鑒于交易核心為支付平臺(tái)的入口,針對(duì) 1.x 支付系統(tǒng)中支付接入無(wú)授權(quán)問(wèn)題,我們也在交易核心里面做了支付接入的管控,授權(quán) & 鑒權(quán)。為任何一個(gè)接入支付的業(yè)務(wù)分配唯一的業(yè)務(wù)標(biāo)識(shí)碼 & 授權(quán)的 token。從而使得業(yè)務(wù)在支付接入時(shí),須帶上 token & 加鹽過(guò)的加密數(shù)據(jù)傳入。
?支付核心
我們將 1.x 支付系統(tǒng)里面的支付模塊,切分兩層,交易核心 & 支付核心。交易核心面向上游業(yè)務(wù),支付核心面向支付系統(tǒng)內(nèi)部。
支付核心整體架構(gòu)如圖 2.6,我們對(duì)支付核心同樣進(jìn)行了支付類(lèi)型的抽象:充值、提現(xiàn)、退款、轉(zhuǎn)賬四類(lèi),任何一個(gè)交易核心訂單請(qǐng)求,都能被四種基礎(chǔ)支付類(lèi)型組合進(jìn)而完成支付行為。另外,支付核心需要基于系統(tǒng)、用戶(hù)指令等完成各種各樣的支付行為。按照簡(jiǎn)單的做法,我們可以在不同的分支上實(shí)現(xiàn)各式的支付行為,但是這樣可能會(huì)導(dǎo)致支付行為的耦合,以及支付的復(fù)雜邏輯判斷。基于這種原因,我們對(duì)支付工具進(jìn)行組件化拆分,封裝為數(shù)十種支付工具,通過(guò)支付編排來(lái)執(zhí)行支付行為。
支付核心架構(gòu)圖
支付行為編排
支付交易訂單通過(guò)支付規(guī)則生成具體的支付請(qǐng)求(即支付核心記錄),支付請(qǐng)求通過(guò)支付指令編排規(guī)則,獲取一組支付工具包。通過(guò)支付執(zhí)行器完成對(duì)支付工具的調(diào)用執(zhí)行。這樣的封裝,我們可以實(shí)現(xiàn)插件式開(kāi)發(fā),以及可支付規(guī)則可配置化,繼而讓支付核心內(nèi)部的支付工具互不影響 & ?系統(tǒng)簡(jiǎn)化。整個(gè)編排過(guò)程如下圖所示:
支付行為編排
異常處理機(jī)制
支付核心有一個(gè)比較重要的功能,是如何對(duì)支付異常進(jìn)行處理,支付過(guò)程比如重復(fù)支付、部分支付、金額不一致、其他異常全額退款等等異常,都需要做異常的退款。
如圖 2.8 以部分支付為例,我們做了一個(gè)異常管理組件來(lái)處理這種異常,在網(wǎng)關(guān)支付 + 紅包 + 優(yōu)惠券組合支付中,對(duì)每次的支付都進(jìn)行上報(bào)。紅包支付、優(yōu)惠券支付,都成功上報(bào),而對(duì)于網(wǎng)關(guān)支付異常時(shí),也做異常上報(bào)機(jī)制。通過(guò)異常管理組件對(duì)部分支付成功的行為進(jìn)行反向異常退款。
部分支付異常退款
?渠道網(wǎng)關(guān)
我們對(duì)渠道網(wǎng)關(guān)系統(tǒng)進(jìn)行拆分,渠道網(wǎng)關(guān)接受來(lái)自支付核心的支付請(qǐng)求,與三方支付進(jìn)行交互。
網(wǎng)關(guān)系統(tǒng)同樣抽象了基礎(chǔ)服務(wù)類(lèi)型:支付、退款、提現(xiàn)、簽約、查詢(xún)等。同時(shí),為了性能考慮,網(wǎng)關(guān)系統(tǒng)切分為兩個(gè)子系統(tǒng),網(wǎng)關(guān)核心 & 網(wǎng)關(guān)前置:
網(wǎng)關(guān)核心負(fù)責(zé)渠道路由、渠道訂單的管理、以及渠道的分組。
網(wǎng)關(guān)前置負(fù)責(zé)渠道適配、報(bào)文轉(zhuǎn)換、以及外部通訊。
整體架構(gòu)如下圖所示
渠道網(wǎng)關(guān)整體架構(gòu)圖
?資金核算體系
資金核算體系主要由賬務(wù)系統(tǒng)、會(huì)計(jì)系統(tǒng)、清算系統(tǒng) 和合規(guī)系統(tǒng)組成,整體架構(gòu)如下圖所示:
支付核算體系
-
賬務(wù)系統(tǒng):由支付核心驅(qū)動(dòng),記錄管理賬戶(hù)信息,直接反應(yīng)用戶(hù)的賬戶(hù)余額和資金變更明細(xì)。
-
會(huì)計(jì)系統(tǒng):對(duì)業(yè)務(wù)運(yùn)轉(zhuǎn)信息進(jìn)行管理、核查、披露。 展現(xiàn)資金的來(lái)龍去脈。
-
清算系統(tǒng):由支付核心驅(qū)動(dòng),實(shí)現(xiàn)機(jī)構(gòu)間資金關(guān)系應(yīng)收應(yīng)付的主被動(dòng)清算以及資金劃撥。
-
合規(guī)系統(tǒng):基于支付數(shù)據(jù),向資金監(jiān)管方同步交易信息流 & 資金流,從而契合央行合規(guī)監(jiān)管要求。
截止目前,我們對(duì)支付體系的面向業(yè)務(wù)的系統(tǒng) & 資金核算體系進(jìn)行了介紹。
統(tǒng)一平臺(tái)業(yè)務(wù)上下文
1.x 支付系統(tǒng)單體應(yīng)用通過(guò)確定系統(tǒng)邊界、業(yè)務(wù)建模拆分之后,整個(gè)支付平臺(tái)被拆分幾十個(gè)服務(wù),而如何保障在服務(wù)間流轉(zhuǎn)業(yè)務(wù)信息不被丟失,是我們需要考慮的問(wèn)題。就好比如何讓各個(gè)系統(tǒng)交互時(shí)都講普通話(huà),而不是講方言。針對(duì)這個(gè)問(wèn)題,我們做了平臺(tái)統(tǒng)一上下文的要素信息(唯一業(yè)務(wù)標(biāo)識(shí)碼),在整個(gè)支付平臺(tái)鏈路中全程傳遞,具體要素如下:
-
商戶(hù):諸如 mgj 交易 & mls 交易等。
-
訂單類(lèi)型:基于交易核心的業(yè)務(wù)類(lèi)型,諸如擔(dān)保交易、即時(shí)交易、轉(zhuǎn)賬、提現(xiàn)等
-
訂單場(chǎng)景:諸如電商預(yù)售、營(yíng)銷(xiāo)廣告購(gòu)買(mǎi)等
-
支付機(jī)構(gòu):諸如支付寶、微信等
通過(guò)統(tǒng)一平臺(tái)業(yè)務(wù)上下文,我們能夠在任何一個(gè)系統(tǒng)里面清晰看出是哪種業(yè)務(wù),在哪種場(chǎng)景下,使用哪個(gè)渠道做了什么事情。
直面數(shù)據(jù)一致性挑戰(zhàn)
在單體應(yīng)用服務(wù)拆分之后,我們碰到了更加嚴(yán)峻的數(shù)據(jù)一致性挑戰(zhàn),系統(tǒng)間交互異常、無(wú)分布式事務(wù)的情況下,數(shù)據(jù)不一致的情況出現(xiàn)的概率還是非常大。
那么我們是如何解決數(shù)據(jù)一致性問(wèn)題的?總結(jié)下來(lái)有三個(gè)方面:
?CAS
在整個(gè)支付平臺(tái)中,我們對(duì)可能有并發(fā)沖突的系統(tǒng)做了 CAS 樂(lè)觀鎖 ,以交易核心、支付核心為例,通過(guò)狀態(tài)的 CAS 樂(lè)觀鎖防止并發(fā),如下所示:
update PayOrder set status='complete' where id=1 and status='process'
同時(shí),也做了基于 KVstore 的分布式緩存鎖來(lái)防止多數(shù)據(jù)之間的并發(fā)問(wèn)題,例如解決重復(fù)支付問(wèn)題等。
?接口冪等 & 異常補(bǔ)償
我們要求整個(gè)支付體系中的所有服務(wù),涉及數(shù)據(jù)變更的接口都要求保持接口冪等。通過(guò)全鏈路的冪等,使得重試成為了可能。
在諸如服務(wù)超時(shí)、網(wǎng)絡(luò)異常的情況下,我們做了兩種不同的異常補(bǔ)償:基于消息中間件 Corgi 的準(zhǔn)實(shí)時(shí)補(bǔ)償 & 基于異常表的補(bǔ)償。
以支付回調(diào)鏈路為例,如下圖所示,渠道網(wǎng)關(guān)和支付核心之間的交互,使用的兩者補(bǔ)償?shù)姆绞健=灰缀诵?對(duì)電商交易的支付成功通知方式,我們使用異常表的補(bǔ)償,在 12 小時(shí)內(nèi)遞衰的通知 10 次等等。
支付回調(diào)補(bǔ)償機(jī)制
?完整對(duì)賬體系
在支付體系中,對(duì)賬是數(shù)據(jù)一致性的最后一道防護(hù)。對(duì)賬可分為兩部分:
內(nèi)外對(duì)賬,是 1.x 支付系統(tǒng)上線(xiàn)之后已經(jīng)實(shí)現(xiàn)該功能。確保美麗聯(lián)合集團(tuán)支付數(shù)據(jù)與三方支付的數(shù)據(jù)保持一致。
內(nèi)部業(yè)務(wù)對(duì)賬,在 2.0 支付體系構(gòu)建過(guò)程中,我們做了一套內(nèi)部業(yè)務(wù)準(zhǔn)實(shí)時(shí)對(duì)賬系統(tǒng),用于核對(duì)整個(gè)平臺(tái)數(shù)據(jù)。
下面對(duì)內(nèi)部準(zhǔn)實(shí)時(shí)做簡(jiǎn)單的介紹:
內(nèi)部準(zhǔn)實(shí)時(shí)對(duì)賬
如下圖所示,準(zhǔn)實(shí)時(shí)對(duì)賬平臺(tái)支持各種數(shù)據(jù)源的接入,目前基于系統(tǒng)解耦的考慮,我們更多的使用數(shù)據(jù)庫(kù)事件變更中間件 Pigeon 來(lái)接入對(duì)賬雙方的 binlog 數(shù)據(jù),通過(guò)配置的規(guī)則 或者自定義的轉(zhuǎn)換邏輯來(lái)進(jìn)行雙方的模型轉(zhuǎn)換,從而通過(guò)對(duì)賬核心進(jìn)行數(shù)據(jù)的核對(duì)。目前通過(guò)該系統(tǒng),我們可以在 5-25min 之內(nèi),發(fā)現(xiàn)異常數(shù)據(jù)。目前支付核心鏈路全部接入,支付全平臺(tái) 95% 以上。同時(shí)由于對(duì)賬系統(tǒng)的普適性,目前已經(jīng)推廣至公司所有業(yè)務(wù)。
準(zhǔn)實(shí)時(shí)對(duì)賬平臺(tái)架構(gòu)圖
基于上述的這些手段,我們能夠保障支付系統(tǒng)數(shù)據(jù)的最終一致性。
療效?
那么通過(guò)對(duì)支付體系的升級(jí)架構(gòu),我們?nèi)〉昧四男┏晒?#xff1f;
快速支撐業(yè)務(wù)。之前在接入新的業(yè)務(wù)的時(shí)候,大概率需要新增交易表以及開(kāi)發(fā)上線(xiàn)。目前在升級(jí)之后,我們基本上只需要進(jìn)行接入配置即可。
16 年快速融合淘世界、美麗說(shuō)支付系統(tǒng)。在融合的過(guò)程中,新版的支付系統(tǒng)能夠兼容當(dāng)時(shí)的淘世界 & 美麗說(shuō)支付系統(tǒng),順利的完成了融合。
基于業(yè)務(wù)接入授權(quán)管控 以及平臺(tái)統(tǒng)一上下文,我們能夠?qū)I(yè)務(wù)進(jìn)行細(xì)分,從而能夠?qū)Ω鳂I(yè)務(wù)的資金情況進(jìn)行細(xì)分和準(zhǔn)確的核實(shí)。
通過(guò)合規(guī)系統(tǒng)的實(shí)現(xiàn),符合央行的資金監(jiān)管要求,為用戶(hù)、商戶(hù)提供了強(qiáng)有力的資金安全保障。
總結(jié)展望
通過(guò)對(duì)業(yè)務(wù)的梳理、系統(tǒng)邊界的拆分、業(yè)務(wù)建模等手段,我們完成了對(duì)支付體系 2.0 架構(gòu)升級(jí),進(jìn)而能夠?qū)I(yè)務(wù)提供更加高效、穩(wěn)定、專(zhuān)業(yè)的支撐。進(jìn)一步的提升了資金的核算 & 管控能力。但是目前的支付平臺(tái)里,每個(gè)子系統(tǒng)中,或多或少的都存在著自己的配置系統(tǒng),雖然是基于公用的統(tǒng)一的平臺(tái)業(yè)務(wù)上下文,但是配置還是繁瑣。如何做到統(tǒng)一化配置也是我們后續(xù)考慮的重點(diǎn)。同時(shí),目前平臺(tái)業(yè)務(wù)統(tǒng)一上下文的四要素是基于交易核心出發(fā),從目前的系統(tǒng)演化來(lái)看,我們需要繼續(xù)改進(jìn)為更優(yōu)化的模型,以應(yīng)對(duì)后續(xù)更加復(fù)雜的各類(lèi)業(yè)務(wù)。
下篇:容量提升
在對(duì)美聯(lián)支付系統(tǒng)升級(jí)到支付體系 2.0 之后(支付體系架構(gòu)演進(jìn))。那么我們針對(duì)電商平臺(tái)特性,比如大促時(shí)支付鏈路峰值為日常的百倍以上等等特性,又做了哪些性能和穩(wěn)定的提升?
下面我們以支付核心鏈路為例,談?wù)勅绾翁嵘Ц镀脚_(tái)的性能和穩(wěn)定性。
支付核心鏈路
性能提升
針對(duì)于電商特性,我們對(duì)支付平臺(tái)的性能提升主要是從以下幾個(gè)方面優(yōu)化:
-
核心鏈路分庫(kù)分表:全鏈路水平擴(kuò)展
-
服務(wù)調(diào)用異步化
-
熱點(diǎn)賬戶(hù)問(wèn)題優(yōu)化
-
事務(wù)切分
核心鏈路分庫(kù)分表:全鏈路水平擴(kuò)展
目前所有的應(yīng)用服務(wù)都是無(wú)狀態(tài),理論上應(yīng)用服務(wù)可以做到無(wú)限擴(kuò)展,目前最大的瓶頸是在 DB。性能容量的提升,關(guān)鍵在于 DB 的容量。基于這個(gè)原因,我們對(duì)整個(gè)平臺(tái)的 DB 做了水平的拆分。
在全平臺(tái)水平擴(kuò)展的過(guò)程中,我們以核心鏈路為例,從交易核心、支付核心、賬務(wù)核心、渠道網(wǎng)關(guān)等系統(tǒng)全部做了數(shù)據(jù)庫(kù)的水平拆分。基于交易核心、支付核心、渠道網(wǎng)關(guān)等系統(tǒng),前面介紹過(guò),我們抽象了各種基礎(chǔ)模型,數(shù)據(jù)都是基于一張主表存儲(chǔ),因此水平拆分基于該主表即可。
得益于美聯(lián)自研的數(shù)據(jù)庫(kù)中間件 Raptor,我們實(shí)現(xiàn)鏈路的分庫(kù)分表。同時(shí),也基于全局統(tǒng)一的 sequence 生成器,保持了所有分片內(nèi)的主鍵 id 唯一性。
支付核心鏈路分庫(kù)分表
服務(wù)調(diào)用異步化
支付體系 2.0 升級(jí)之后,單體應(yīng)用拆分為數(shù)十個(gè)服務(wù)。系統(tǒng)的拆分和服務(wù)化,其實(shí)帶來(lái)了更多的系統(tǒng)依賴(lài)。相對(duì)于之前的單體應(yīng)用,從方法級(jí)的調(diào)用方式變更為 RPC 服務(wù)調(diào)用,網(wǎng)絡(luò)耗時(shí) & 同時(shí)網(wǎng)絡(luò)的穩(wěn)定性等因素也是需要考慮的問(wèn)題。基于這些考慮,非強(qiáng)實(shí)時(shí)的服務(wù)調(diào)用,異步化是最佳的解耦方式。同樣,在核心鏈路里,我們也做了各種各樣的異步化優(yōu)化,進(jìn)而提升整體的鏈路性能,滿(mǎn)足電商平臺(tái)獨(dú)有的性能特性要求。
我們從幾個(gè)點(diǎn)來(lái)看下如何對(duì)支付系統(tǒng)做異步處理:
?支付消息報(bào)
基于數(shù)據(jù)庫(kù)事件中間件 Pigeon & 消息隊(duì)列 Corgi,我們實(shí)現(xiàn)支付消息報(bào)。如圖 1.2 所示,支付消息報(bào)基于交易核心數(shù)據(jù),聚合支付核心的支付數(shù)據(jù),最終生成支付消息報(bào)。通過(guò)這種方式,將原本需要在交易核心或者支付核心調(diào)用下游業(yè)務(wù)方,或者下游業(yè)務(wù)方實(shí)時(shí)查詢(xún)的方式,轉(zhuǎn)變?yōu)橄掠螛I(yè)務(wù)方通過(guò)接受消息的推送來(lái)獲取數(shù)據(jù),從而達(dá)到了業(yè)務(wù)的解耦。同時(shí),也簡(jiǎn)化了業(yè)務(wù)方的數(shù)據(jù)獲取復(fù)雜度。
支付消息報(bào)架構(gòu)圖
目前支付消息報(bào)已經(jīng)接入了 10 多個(gè)業(yè)務(wù)場(chǎng)景,例如滿(mǎn)返,支付成功短信通知,風(fēng)控所需的支付數(shù)據(jù)等等,并在持續(xù)不斷的增加中。
?外部支付異步化
在外部支付中,經(jīng)常會(huì)碰到這種情況,需要服務(wù)方與第三方支付交互,獲取預(yù)支付憑證,如圖 1.3 所示。這種同步調(diào)用的情況下,由于需要跨外部網(wǎng)絡(luò),響應(yīng)的 RT 會(huì)非常長(zhǎng),可能會(huì)出現(xiàn)跨秒的情況。由于是同步調(diào)用,會(huì)阻塞整個(gè)支付鏈路。一旦 RT 很長(zhǎng)且 QPS 比較大的情況下,服務(wù)會(huì)整體 hold 住,甚至?xí)霈F(xiàn)拒絕服務(wù)的情況。
同步調(diào)用三方支付
基于這個(gè)問(wèn)題,我們對(duì)這種獲取預(yù)支付憑證的方式進(jìn)行了改進(jìn),詳見(jiàn)下圖:
異步調(diào)用三方支付
通過(guò)獨(dú)立網(wǎng)關(guān)渠道前置服務(wù),將獲取的方式分為兩個(gè)步驟:
針對(duì)支付鏈路,只是請(qǐng)求到渠道前置拿到內(nèi)部的支付憑證就結(jié)束了。
針對(duì)外部請(qǐng)求,由渠道前置異步向三方支付發(fā)起請(qǐng)求。
那么基于這種方式,與三方支付的同步交互僅僅會(huì)阻塞渠道前置。密集型的 io & 低 cpu 系統(tǒng),渠道前置的并發(fā)值可以設(shè)置的非常大。
?異步并行
支付平臺(tái)服務(wù)化之后,核心鏈路上的服務(wù)多為 IO 密集型,這里我們以收銀臺(tái)渲染為例,見(jiàn)下圖。
串行模式下的收銀臺(tái)渲染
一次收銀臺(tái)渲染,串行的調(diào)用各個(gè)服務(wù)來(lái)進(jìn)行用戶(hù)信息查詢(xún) (RT T1)、額度查詢(xún) (RT T2)、優(yōu)惠查詢(xún) (RT T3),最終執(zhí)行渠道渲染 (RT T4),這種實(shí)現(xiàn)方式下
收銀臺(tái)的渲染 RT = sum(T1,T2,T3,T4)
但是收銀臺(tái)的渲染 RT 必須要這么久嗎?其實(shí)對(duì)于業(yè)務(wù)的分析,我們發(fā)現(xiàn)其實(shí)很多的服務(wù)調(diào)用無(wú)先后順序。用戶(hù)信息查詢(xún)、額度查詢(xún)、優(yōu)惠查詢(xún)這三個(gè)服務(wù)的調(diào)用其實(shí)無(wú)先后順序,那么我們基于 Tesla 服務(wù)框架的異步化服務(wù)調(diào)用,見(jiàn)下圖。
異步并行模式下的收銀臺(tái)渲染
基于異步并行的收銀臺(tái)渲染方式,將并行過(guò)程中的各服務(wù)化的耗時(shí)之和變更為耗時(shí)最長(zhǎng)的一個(gè)服務(wù)的 RT。
收銀臺(tái)渲染 RT =sum(max(T1,T2,T3),T4)
?資金核算體系異步化
目前支付平臺(tái)里,資金核算體系各個(gè)子系統(tǒng):會(huì)計(jì)系統(tǒng)數(shù)據(jù)來(lái)源于賬務(wù)系統(tǒng),賬務(wù) 、清算 、合規(guī)數(shù)據(jù)來(lái)源于支付核心。那么,需要在支付核心鏈路執(zhí)行的時(shí)候同步調(diào)用賬務(wù) & 清算 & 合規(guī),賬務(wù)實(shí)時(shí)調(diào)用會(huì)計(jì)嗎?其實(shí)基于對(duì)資金業(yè)務(wù)的分析,會(huì)計(jì)、清算、合規(guī)屬于非強(qiáng)實(shí)時(shí)業(yè)務(wù),可以通過(guò)數(shù)據(jù)變更中間件 Pigeon 同步數(shù)據(jù),對(duì)這三個(gè)系統(tǒng)進(jìn)行了解耦,如圖:
資金核算體系異步化架構(gòu)
清算、合規(guī)通過(guò)監(jiān)聽(tīng)支付核心 DB 數(shù)據(jù)變更來(lái)獲取數(shù)據(jù),會(huì)計(jì)通過(guò)監(jiān)聽(tīng)賬務(wù)的流水庫(kù)的數(shù)據(jù)變更來(lái)獲取數(shù)據(jù),從而對(duì)實(shí)時(shí)鏈路非強(qiáng)實(shí)時(shí)業(yè)務(wù)進(jìn)行解耦。
熱點(diǎn)賬戶(hù)問(wèn)題優(yōu)化
熱點(diǎn)賬戶(hù)應(yīng)該是每一個(gè)做支付的童鞋都會(huì)碰到的問(wèn)題。美聯(lián)的支付系統(tǒng)里,存在這各種各樣的熱點(diǎn)賬戶(hù),我們將之分為三類(lèi):
內(nèi)部戶(hù):比如渠道的待清分賬號(hào)等
平臺(tái)戶(hù):比如各種平臺(tái)的營(yíng)銷(xiāo)的墊支戶(hù)等
大商家的熱點(diǎn)賬戶(hù)等。
每種熱點(diǎn)賬戶(hù)的業(yè)務(wù)屬性都不一樣,比如商家賬戶(hù),我們不能延遲記賬等等。基于這些情況,我們對(duì)熱點(diǎn)賬戶(hù)問(wèn)題優(yōu)化也基于類(lèi)型:
內(nèi)部戶(hù)
針對(duì)于內(nèi)部戶(hù),我們?cè)谫~務(wù)中不做內(nèi)部戶(hù)這邊的記賬,而是由會(huì)計(jì)通過(guò)另外一邊的賬務(wù)流水去補(bǔ)分錄。
平臺(tái)戶(hù)
針對(duì)于平臺(tái)戶(hù),在賬務(wù)中做了異步記賬,通過(guò)定時(shí)匯總記賬即可。
大商家
比較難的是大商家的熱點(diǎn)問(wèn)題,特別是在美聯(lián)這種沒(méi)有商家結(jié)算周期的情況下,每一筆的訂單狀態(tài)變更,都有可能涉及商家的賬戶(hù)資金變更。但是也有解決辦法。分析其業(yè)務(wù)場(chǎng)景,擔(dān)保入賬、擔(dān)保出賬 、傭金扣費(fèi)等占用了絕大多數(shù)的商家賬戶(hù)操作。針對(duì)這塊我們分為兩個(gè)點(diǎn)來(lái)做優(yōu)化:
將商家擔(dān)保賬戶(hù)切換到平臺(tái)擔(dān)保戶(hù),基于流水去統(tǒng)計(jì)商家擔(dān)保中的金額。這種情況下,擔(dān)保入賬和出賬的商家熱點(diǎn)問(wèn)題可以解決。
第一點(diǎn)的優(yōu)化能夠解決擔(dān)保出入賬的賬務(wù)操作,但是扣費(fèi)依舊會(huì)造成大量的熱點(diǎn)賬戶(hù)問(wèn)題,對(duì)此我們做了一個(gè)排序的任務(wù),將扣費(fèi)做到做到單商家串行 & 多商家并行。
基于上述的兩個(gè)優(yōu)化方案,我們解決了大商家熱點(diǎn)賬戶(hù)問(wèn)題。
通過(guò)對(duì)三種類(lèi)型的熱點(diǎn)賬戶(hù)優(yōu)化進(jìn)行,能夠解決目前系統(tǒng)碰到的熱點(diǎn)賬戶(hù)問(wèn)題。但是各種平臺(tái)戶(hù)的賬務(wù)流水會(huì)非常多,以擔(dān)保戶(hù)為例,每日的所有的出入擔(dān)保戶(hù)的流水,都會(huì)在這個(gè)賬戶(hù)之上,那么在分庫(kù)分表情況下,會(huì)出現(xiàn)平臺(tái)戶(hù)所在的單表巨大無(wú)比。在這里我們引入二級(jí)子賬戶(hù)概念,將內(nèi)部戶(hù) & 平臺(tái)戶(hù)在賬務(wù)虛化成 N 個(gè)二級(jí)子賬戶(hù),從而均勻的分散在各個(gè)分表里,進(jìn)而解決了該問(wèn)題。
賬務(wù)記賬事務(wù)切分
在支付核心鏈路里,我們對(duì)非強(qiáng)實(shí)時(shí)依賴(lài)的服務(wù)做了異步化的解耦,對(duì)熱點(diǎn)賬戶(hù)進(jìn)行了優(yōu)化的處理。在賬務(wù)記賬的時(shí)候,我們從下面兩個(gè)問(wèn)題考慮優(yōu)化點(diǎn):
在賬務(wù)分庫(kù)分表的情況下,如何保證記賬是在事務(wù)里?
每次記賬的出賬 & 入賬是否可拆分?
基于這兩個(gè)問(wèn)題,我們對(duì)記賬流程進(jìn)行了事務(wù)的拆分,如圖所示:
賬務(wù)記賬事務(wù)拆分
出賬、入賬分離。出賬成功,則整體成功,入賬失敗可以異步補(bǔ)賬。
出賬 & 入賬 ,每個(gè)里面都做單邊賬、異步記賬等處理,整個(gè)支付核心鏈路唯一的一個(gè)事務(wù)就在于更新賬務(wù)余額 ?& 新增流水。
目前系統(tǒng)中,經(jīng)過(guò)這一系列的優(yōu)化,單次的記賬性能,基本上穩(wěn)定在 15ms 左右。
穩(wěn)定性提升
在上文中,我們主要針對(duì)于支付鏈路的性能做了各種各樣的性能提升。資金無(wú)小事,如何保證支付平臺(tái)的穩(wěn)定性,也是我們需要考慮的重點(diǎn)。我們從下面幾個(gè)維度來(lái)提升穩(wěn)定性。
監(jiān)控先行
做穩(wěn)定性之前,我們需要知道我們的系統(tǒng)運(yùn)行情況,那么必須要做線(xiàn)上系統(tǒng)的監(jiān)控,對(duì)關(guān)鍵指標(biāo)進(jìn)行管控,以支付核心鏈路為例,如圖:
核心鏈路監(jiān)控
如圖所示,我們監(jiān)控了核心鏈路的 qps、rt、并發(fā)量等,同時(shí)也基于支付核心,我們對(duì)依賴(lài)的服務(wù) qps、rt 進(jìn)行監(jiān)控。另外,也對(duì)依賴(lài)的 DB & Cache 進(jìn)行監(jiān)控。
通過(guò)在監(jiān)控大盤(pán)中配置關(guān)鍵指標(biāo),能夠比較清晰明了的看出目前核心鏈路線(xiàn)上運(yùn)行情況。
分離核心鏈路
基于電商特性,我們對(duì)整個(gè)核心鏈路進(jìn)行了剝離,如圖所示:
分離核心鏈路
對(duì)核心鏈路分離的過(guò)程中,我們對(duì)鏈路中的各個(gè)服務(wù)中切分為核心 & 通用服務(wù)。分離的做法其實(shí)有很多,比如基于 Tesla 服務(wù)框架提供的服務(wù)分組功能;比如將一個(gè)服務(wù)切分為兩個(gè)服務(wù):核心鏈路服務(wù)和通用查詢(xún)服務(wù)。
在核心鏈路分離之后,能夠確保在任何時(shí)候,核心鏈路不會(huì)受到其他通用業(yè)務(wù)的影響而導(dǎo)致出現(xiàn)穩(wěn)定性問(wèn)題。
服務(wù)依賴(lài)梳理
目前在支付系統(tǒng)里,有著數(shù)十個(gè)服務(wù),如果不對(duì)服務(wù)依賴(lài)進(jìn)行梳理,系統(tǒng)穩(wěn)定性會(huì)得不到保障。我們從下面幾點(diǎn)來(lái)梳理服務(wù)依賴(lài):
梳理平臺(tái)中的強(qiáng)弱依賴(lài),判定哪些是強(qiáng)依賴(lài),哪些是弱依賴(lài)。
弱依賴(lài)做好降級(jí)和超時(shí)保護(hù),比如收銀臺(tái)渲染是的白付美額度查詢(xún),這種可以埋降級(jí)開(kāi)關(guān) & 設(shè)置較短的超時(shí)時(shí)間。因?yàn)椴椴坏筋~度,最多不能使用白付美支付,并不會(huì)有特別大的影響。
如果是強(qiáng)依賴(lài),這個(gè)不能降級(jí),怎么辦?需要對(duì)強(qiáng)依賴(lài)的服務(wù)提出服務(wù)的 SLA 治理,比如賬務(wù)記賬功能,我們會(huì)要求系統(tǒng)不能掛、rt 不能超過(guò) 20ms,qps 需要支撐 8k qps 等等,基于這個(gè)約定,做子服務(wù)的優(yōu)化。
降級(jí)、限流
限流是保護(hù)系統(tǒng)不掛的最后一道防線(xiàn)。
目前支付平臺(tái)里面,存在基于 RPC 服務(wù)框架 tesla 的粗粒度限流,可控制在服務(wù)級(jí)別和方法級(jí)別;基于 spirit 的細(xì)粒度限流降級(jí)系統(tǒng),我們可以在單個(gè)方法里面做限流降級(jí)功能個(gè),如下圖所示,我們?cè)趽?dān)保交易下單過(guò)程中,區(qū)分平臺(tái)來(lái)源,做到蘑菇街擔(dān)保交易流量 & 美麗說(shuō)擔(dān)保交易流量。
spirit 限流模式
但是不得不說(shuō),單單的 qps 或者并發(fā)限流都不能完全的做好限流保護(hù),需要兩者的相結(jié)合才能達(dá)到所需的效果。
另外一點(diǎn),通過(guò)對(duì)服務(wù)的依賴(lài)梳理,我們?cè)诟鞣N弱依賴(lài)的服務(wù)中埋了一些降級(jí)開(kāi)關(guān)。通過(guò)自研的降級(jí)推送平臺(tái),一旦依賴(lài)服務(wù)出現(xiàn)問(wèn)題或者不可用,可以快速的對(duì)該服務(wù)進(jìn)行降級(jí)操作。
壓測(cè)怎么做?
在對(duì)系統(tǒng)擴(kuò)容,鏈路性能優(yōu)化之后,怎么檢測(cè)成果呢?
我們引入線(xiàn)上壓測(cè)系統(tǒng),通過(guò)分析業(yè)務(wù)場(chǎng)景,構(gòu)建與線(xiàn)上真實(shí)場(chǎng)景幾乎一致的測(cè)試模型。以支付鏈路為例,模型中以日常 & 大促的流量模型為基準(zhǔn),設(shè)計(jì)壓測(cè)模型。需要注意的是,壓測(cè)模型越與真實(shí)一致,壓測(cè)的效果越好,對(duì)系統(tǒng)把控越準(zhǔn)確。。
通過(guò)構(gòu)建線(xiàn)上數(shù)據(jù)影子庫(kù),壓測(cè)產(chǎn)生的測(cè)試數(shù)據(jù),會(huì)全量寫(xiě)入到影子庫(kù)中。通過(guò)影子庫(kù),在復(fù)用線(xiàn)上正式業(yè)務(wù)一致的環(huán)境、部署、機(jī)器資源下,我們能夠做到壓測(cè)對(duì)正常業(yè)務(wù)無(wú)侵入,對(duì)系統(tǒng)做準(zhǔn)確的把脈。
線(xiàn)上業(yè)務(wù)也分為兩塊,一塊是單機(jī)性能壓測(cè),主要是分析單機(jī)的性能水位和各項(xiàng)指標(biāo)。另外是鏈路壓測(cè),主要驗(yàn)證系統(tǒng)的穩(wěn)定性和服務(wù)短板。
通過(guò)壓測(cè)的結(jié)果,我們能夠?qū)χЦ镀脚_(tái)的性能 & 穩(wěn)定性短板的分析和加以改進(jìn),能夠不斷的提升系統(tǒng)的穩(wěn)定性,提升系統(tǒng)的容量。
療效?
那么,通過(guò)一系列的性能容量的提升,我們達(dá)到了什么效果?
平臺(tái)容量方面:在 16 年雙十一的大促壓測(cè)中,我們?cè)阪溌?DB 都擴(kuò)圍兩組的物理的機(jī)器情況下,支付穩(wěn)定在 3000QPS。由于目前沒(méi)有需求,我們未對(duì) DB 的物理機(jī)器擴(kuò)到極限,因此系統(tǒng)的極限性能不能完全確定,但是按照預(yù)估,理論上可支持 1w QPS 以上。
機(jī)器利用率上:相同的容量情況下,我們的應(yīng)用減少為原有的 1/3。
鏈路的性能上:如圖 4.1 所示,以擔(dān)保交易為例,交易核心的收單 rt 幾乎在 10ms,而收銀臺(tái)渲染在 50ms,支付請(qǐng)求在 50ms,支付回調(diào)在 80ms 左右。
核心鏈路服務(wù)性能
同時(shí),基于性能和穩(wěn)定性的提升,我們做到了支付在歷次的大促中,保持無(wú)故障的記錄。
總結(jié)展望
在美聯(lián)支付系統(tǒng)中,上層支付業(yè)務(wù)面向電商平臺(tái),針對(duì)電商特色做更多的業(yè)務(wù)支持。我們對(duì)平臺(tái)的性能容量尋找可改進(jìn)的地方,比如 DB、Cache、IO、以及異步化,持續(xù)不斷去優(yōu)化。另外,資金無(wú)小事,如何提升支付系統(tǒng)的穩(wěn)定性也是重點(diǎn)考慮的方向。
轉(zhuǎn)載于:https://www.cnblogs.com/davidwang456/p/7550020.html
總結(jié)
以上是生活随笔為你收集整理的一个细节翔实、可供参考的支付体系架构演进实例--转的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 20个非常有用的Java程序片段--转
- 下一篇: 就是这么迅猛的实现搜索需求--转