使用微服務(wù)架構(gòu)重構(gòu)支付網(wǎng)關(guān)

在支付系統(tǒng)改進(jìn)中况芒,我們對(duì)原有系統(tǒng)做了整體的評(píng)估惜纸,選擇支付網(wǎng)關(guān)作為入手點(diǎn)來(lái)進(jìn)行微服務(wù)架構(gòu)的改進(jìn)。這里詳細(xì)介紹我們針對(duì)該模塊的改進(jìn)過(guò)程绝骚,供參考耐版。

原有系統(tǒng)情況

早期啟動(dòng)的時(shí)候,對(duì)接的支付渠道不多压汪,所有支付渠道和支付網(wǎng)關(guān)都實(shí)現(xiàn)在一個(gè)項(xiàng)目中粪牲,部署在一起。其中支付網(wǎng)關(guān)是整個(gè)項(xiàng)目的核心和入手點(diǎn)止剖。它為各個(gè)業(yè)務(wù)方提供支付全流程的調(diào)用接口腺阳,簽約、代扣穿香、支付亭引、驗(yàn)證,都是通過(guò)這個(gè)接口來(lái)實(shí)現(xiàn)的皮获。整個(gè)系統(tǒng)使用SSH框架焙蚓,架構(gòu)如下:

業(yè)務(wù)流程如下:

當(dāng)接口被調(diào)用時(shí), 首先執(zhí)行參數(shù)校驗(yàn)洒宝,確認(rèn)輸入的參數(shù)的合法性购公,驗(yàn)證參數(shù)簽名是否正確。確認(rèn)過(guò)程包括調(diào)用賬戶(hù)雁歌、用戶(hù)宏浩、支付方式、路由等服務(wù)來(lái)驗(yàn)證用戶(hù)ID将宪、賬戶(hù)绘闷、支付卡號(hào)橡庞、支付金額等參數(shù)。

根據(jù)輸入的支付方式印蔗,調(diào)用支付路由服務(wù)扒最,獲取對(duì)應(yīng)的支付渠道。

調(diào)用風(fēng)控接口進(jìn)行驗(yàn)證华嘹,如果有交易風(fēng)險(xiǎn)吧趣,則阻斷本次交易。

生成交易記錄耙厚;

調(diào)用支付渠道提供的服務(wù)執(zhí)行支付强挫。

根據(jù)支付結(jié)果,更新訂單狀態(tài)薛躬;

通知商戶(hù)訂單執(zhí)行結(jié)果俯渤。

在實(shí)現(xiàn)上,原有系統(tǒng)實(shí)現(xiàn)的類(lèi)結(jié)構(gòu)圖如下:

采用SSH架構(gòu)型宝,支付網(wǎng)關(guān)實(shí)現(xiàn)為一個(gè)大Apache Struts Action類(lèi)八匠,和支付相關(guān)的所有業(yè)務(wù)邏輯都實(shí)現(xiàn)在一個(gè)項(xiàng)目中。

支付網(wǎng)關(guān)承載大量的功能趴酣,實(shí)際上梨树,它是將API網(wǎng)關(guān)和業(yè)務(wù)邏輯都混在在一起實(shí)現(xiàn)。 簽約岖寞、支付抡四、代扣、驗(yàn)證仗谆,都在這一個(gè)類(lèi)中實(shí)現(xiàn)指巡,代碼行數(shù)超過(guò)1000行,邏輯十分復(fù)雜胸私。

除了風(fēng)控是進(jìn)程外調(diào)動(dòng)厌处,其他的服務(wù)都是進(jìn)程內(nèi)調(diào)用,通過(guò)springframework來(lái)管理各個(gè)service岁疼。

最終落地調(diào)用的支付渠道,是通過(guò)抽象的接口來(lái)對(duì)網(wǎng)關(guān)封裝渠道的差異缆娃。

在這個(gè)系統(tǒng)中對(duì)接了有30多個(gè)渠道捷绒,類(lèi)規(guī)模達(dá)到2000個(gè)。隨著業(yè)務(wù)發(fā)展贯要,問(wèn)題越來(lái)越多暖侨。高峰期同時(shí)有5個(gè)渠道在并行開(kāi)發(fā),還有大量的其他渠道對(duì)接問(wèn)題需要修復(fù)崇渗。多個(gè)人同時(shí)修改一個(gè)項(xiàng)目代碼導(dǎo)致版本控制的工作驟增字逗。上線(xiàn)頻發(fā)引起服務(wù)中斷也讓業(yè)務(wù)方很不滿(mǎn)京郑。對(duì)支付網(wǎng)關(guān)的改進(jìn)是一個(gè)循序漸進(jìn)的過(guò)程。這里參考Arun Gupta的微服務(wù)六種設(shè)計(jì)模式葫掉,來(lái)描述我們所做的改進(jìn)些举。

新網(wǎng)關(guān)設(shè)計(jì) (Chain Pattern)

為了分解舊網(wǎng)關(guān)的功能, 我們?cè)O(shè)計(jì)了新的網(wǎng)關(guān)俭厚。在處理流程上户魏,將其分為三個(gè)步驟,采用的是chain模式挪挤。

鏈?zhǔn)侥J降鸪螅缟蠄D所示,它調(diào)用服務(wù)A來(lái)獲取結(jié)果扛门,而服務(wù)A是通過(guò)服務(wù)B來(lái)交互鸠信,B則會(huì)和C有交互。 整個(gè)過(guò)程類(lèi)似同步的HTTP請(qǐng)求论寨、響應(yīng)處理症副。 這其中每個(gè)階段的調(diào)用,都是阻塞式的同步調(diào)用政基。每一步都會(huì)增加一些業(yè)務(wù)邏輯處理贞铣。

原支付網(wǎng)關(guān)難以維護(hù)的一個(gè)重要原因是其所承載的功能過(guò)多。我們首先根據(jù)用戶(hù)的使用場(chǎng)景沮明,將支付網(wǎng)關(guān)承載的功能辕坝,按照支付產(chǎn)品來(lái)進(jìn)行切分。 支付產(chǎn)品包括快捷支付荐健、網(wǎng)銀支付酱畅、外卡支付等。 不同的產(chǎn)品江场,其對(duì)應(yīng)的操作所使用的參數(shù)和流程也不一樣纺酸。以快捷產(chǎn)品為例, 新網(wǎng)關(guān)接收到請(qǐng)求后址否,根據(jù)用戶(hù)所選擇的支付類(lèi)型餐蔬,分發(fā)到快捷支付產(chǎn)品接口∮痈剑快捷支付產(chǎn)品接口調(diào)用工行借記卡通道來(lái)執(zhí)行支付樊诺,通道最終落地到工行接口的調(diào)用來(lái)實(shí)現(xiàn)支付。 支付操作完成后音同,工行接口通知到通道词爬,通道通知到產(chǎn)品,最終逆向傳遞到網(wǎng)關(guān)接口权均,并最終發(fā)送給調(diào)用方顿膨。 在這里面锅锨,支付網(wǎng)關(guān)負(fù)責(zé)分發(fā)、驗(yàn)簽等基本功能恋沃,支付產(chǎn)品負(fù)責(zé)參數(shù)校驗(yàn)必搞、路由、生成交易記錄等功能芽唇。最終的支付操作是落地到支付渠道去執(zhí)行顾画。

網(wǎng)關(guān)拆分(Proxy Pattern)

如上所述,支付網(wǎng)關(guān)按照使用場(chǎng)景進(jìn)行拆分匆笤。我們采用完善一個(gè)研侣、接入一個(gè)的原則,在保留舊網(wǎng)關(guān)的功能的同時(shí)炮捧,開(kāi)發(fā)完善新的網(wǎng)關(guān)和支付產(chǎn)品庶诡。等所有流量都打到新網(wǎng)關(guān)上去之后,舊網(wǎng)關(guān)就直接廢棄了咆课。為了達(dá)到這個(gè)目標(biāo)末誓,我們引入了代理模式:

代理模式和聚合模式類(lèi)似,不同點(diǎn)在于书蚪,它會(huì)根據(jù)業(yè)務(wù)邏輯需要僅選擇一個(gè)微服務(wù)來(lái)調(diào)用喇澡。微服務(wù)中,我們經(jīng)常會(huì)用代理模式來(lái)構(gòu)建API網(wǎng)關(guān)殊校。

我們首先按照所支持的支付方式晴玖,對(duì)支付網(wǎng)關(guān)做分解,拆分為為網(wǎng)銀为流、快捷呕屎、話(huà)費(fèi)、賬戶(hù)敬察、外卡秀睛、虛幣等支付產(chǎn)品。新網(wǎng)關(guān)接口模塊是一個(gè)proxy莲祸,本身并未實(shí)現(xiàn)任何業(yè)務(wù)邏輯蹂安,它的工作是將用戶(hù)請(qǐng)求發(fā)送給合適的支付產(chǎn)品去處理。如果這個(gè)產(chǎn)品還沒(méi)有實(shí)現(xiàn)虫给,則將其轉(zhuǎn)發(fā)到老網(wǎng)關(guān)去執(zhí)行藤抡。這樣帶來(lái)的好處是,我們不需要對(duì)老網(wǎng)關(guān)做任何改動(dòng)抹估。而且,如果某個(gè)支付產(chǎn)品在重構(gòu)過(guò)程中出現(xiàn)問(wèn)題弄兜,我們可以很快切回到老網(wǎng)關(guān)去药蜻。

支付產(chǎn)品 (Aggregator Pattern)

支付產(chǎn)品是對(duì)原有支付網(wǎng)關(guān)的業(yè)務(wù)流程實(shí)現(xiàn)的一個(gè)重構(gòu)瓷式,按照各個(gè)支付產(chǎn)品所支持的功能以及流程來(lái)簡(jiǎn)化原混合在一起的設(shè)計(jì)。比如快捷支付需要簽約和支付语泽,而網(wǎng)銀支付則不需要簽約贸典。 在支付產(chǎn)品本身的實(shí)現(xiàn)上,我們使用的是聚合模式踱卵。

聚合是最常見(jiàn)的微服務(wù)設(shè)計(jì)模式廊驼,它是一個(gè)高層次的微服務(wù)組合,供其他服務(wù)調(diào)用惋砂。 在這種情況下妒挎,聚合器會(huì)從其他的微服務(wù)中收集數(shù)據(jù),做業(yè)務(wù)邏輯處理西饵,然后發(fā)布成一個(gè)服務(wù)終端酝掩。其他有需要的服務(wù)可以調(diào)用它。 聚合器設(shè)計(jì)的要點(diǎn)是要遵循DRY(Don’t Repeat Yourself)原則眷柔。如果有多個(gè)服務(wù)需要訪(fǎng)問(wèn)A期虾,B,C服務(wù)驯嘱,那建議的處理方式是镶苞,針對(duì)這些使用,提煉一個(gè)處理邏輯出來(lái)鞠评,將A茂蚓、B、C封裝為一個(gè)新的服務(wù)谢澈,這個(gè)服務(wù)可以獨(dú)立的演化煌贴。

支付產(chǎn)品中調(diào)用的各個(gè)服務(wù),包括支付方式管理锥忿, 支付服務(wù)管理牛郑,支付路由管理、支付記錄管理等敬鬓,都被重構(gòu)為微服務(wù)淹朋,在支付產(chǎn)品的實(shí)現(xiàn)中,通過(guò)Aggregator 模式進(jìn)行調(diào)用钉答。

在支付產(chǎn)品的實(shí)現(xiàn)流程中础芍,首先需要對(duì)參數(shù)進(jìn)行校驗(yàn),校驗(yàn)成功后数尿,調(diào)用風(fēng)控檢查該交易是否可以放行仑性。這兩個(gè)操作,在處理上可以并行右蹦,使用的是分支模式。

分支模式是聚合模式的擴(kuò)展,可以允許同時(shí)調(diào)用兩個(gè)或者更多的微服務(wù)轨蛤。

如上,采用分支模式豹储, 使得數(shù)據(jù)校驗(yàn)和風(fēng)控可以并發(fā)執(zhí)行。由于風(fēng)控相對(duì)耗時(shí)較長(zhǎng)淘这,而訂單中需要校驗(yàn)的數(shù)據(jù)較多剥扣,這兩個(gè)操作有必要并發(fā)執(zhí)行。

支付通道 (Aggregator Pattern)

支付路由根據(jù)用戶(hù)選擇的支付方式對(duì)支付通道進(jìn)行篩選铝穷,選取合適的支付通道钠怯。支付產(chǎn)品調(diào)用該通道的接口來(lái)最終落地完成支付服務(wù)。 每個(gè)支付通道對(duì)接也被實(shí)現(xiàn)為微服務(wù)氧骤,在支付產(chǎn)品中調(diào)用呻疹。

通知商戶(hù) (Asynchronous Messaging Pattern)

支付產(chǎn)品執(zhí)行的最后一個(gè)步驟是通知調(diào)用方支付的結(jié)果。 原系統(tǒng)實(shí)現(xiàn)是將這個(gè)步驟耦合在原有代碼中筹陵,容易受到調(diào)用方接口的穩(wěn)定性的影響刽锤。 為此,這里采用異步消息的模式來(lái)進(jìn)行重構(gòu):

異步消息一般用于對(duì)流程中可以異步執(zhí)行的操作做分解朦佩,將它從原流程中分離出來(lái)并思,通過(guò)消息機(jī)制來(lái)異步執(zhí)行。 支付產(chǎn)品在完成支付服務(wù)后语稠,發(fā)出消息到訂單消息隊(duì)列中宋彼。 商戶(hù)回調(diào)處理程序接收到消息后,調(diào)用商戶(hù)回調(diào)接口告知支付結(jié)果仙畦。 此外输涕,風(fēng)控、BI系統(tǒng)等慨畸,也可以使用這個(gè)消息來(lái)同步訂單數(shù)據(jù)莱坎。

總結(jié)

這里簡(jiǎn)單介紹了支付網(wǎng)關(guān)重構(gòu)的過(guò)程,以及如何使用微服務(wù)設(shè)計(jì)模式寸士。 當(dāng)然檐什,這里我們也忽略了很多細(xì)節(jié),比如支付網(wǎng)關(guān)所依賴(lài)的基礎(chǔ)服務(wù)的開(kāi)發(fā)弱卡。 最終的支付網(wǎng)關(guān)的架構(gòu)乃正,參考《支付網(wǎng)關(guān)設(shè)計(jì)》一文。這里涉及到的支付路由婶博、支付記錄瓮具、支付風(fēng)控等模塊的設(shè)計(jì),后續(xù)也會(huì)在本博客中做介紹。 微服務(wù)化改造并不難搭综,需要的是對(duì)原有系統(tǒng)有深入的了解垢箕,然后運(yùn)用各種模式來(lái)拆分划栓,庖丁解牛兑巾。拆分的每一步都需要注意,在設(shè)計(jì)上忠荞,需要考慮一旦出現(xiàn)問(wèn)題即可回滾蒋歌。

感謝您對(duì)本文的關(guān)注,如需要及時(shí)收到鳳凰牌老熊的最新作品委煤,或者有相關(guān)問(wèn)題探討堂油,請(qǐng)掃碼關(guān)注“鳳凰牌老熊”的微信公眾號(hào),在公眾號(hào)里留言或者回復(fù)碧绞,可以盡快處理府框,謝謝。

本文來(lái)自 微信公眾號(hào)“鳳凰牌老熊”讥邻。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末迫靖,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子兴使,更是在濱河造成了極大的恐慌系宜,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件发魄,死亡現(xiàn)場(chǎng)離奇詭異盹牧,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)励幼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)汰寓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人苹粟,你說(shuō)我怎么就攤上這事有滑。” “怎么了六水?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵俺孙,是天一觀(guān)的道長(zhǎng)。 經(jīng)常有香客問(wèn)我掷贾,道長(zhǎng)睛榄,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任想帅,我火速辦了婚禮场靴,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己旨剥,他們只是感情好咧欣,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著轨帜,像睡著了一般魄咕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上蚌父,一...
    開(kāi)封第一講書(shū)人閱讀 49,816評(píng)論 1 290
  • 那天哮兰,我揣著相機(jī)與錄音,去河邊找鬼苟弛。 笑死喝滞,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的膏秫。 我是一名探鬼主播右遭,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼缤削!你這毒婦竟也來(lái)了窘哈?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤僻他,失蹤者是張志新(化名)和其女友劉穎宵距,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體吨拗,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡满哪,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了劝篷。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片哨鸭。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖娇妓,靈堂內(nèi)的尸體忽然破棺而出像鸡,到底是詐尸還是另有隱情,我是刑警寧澤哈恰,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布只估,位于F島的核電站,受9級(jí)特大地震影響着绷,放射性物質(zhì)發(fā)生泄漏蛔钙。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一荠医、第九天 我趴在偏房一處隱蔽的房頂上張望吁脱。 院中可真熱鬧桑涎,春花似錦、人聲如沸兼贡。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)遍希。三九已至等曼,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間孵班,已是汗流浹背涉兽。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留篙程,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓别厘,卻偏偏與公主長(zhǎng)得像虱饿,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子触趴,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容