歡迎光臨
每天分享高質量文章

.NET 架構篇:實用中小型公司支付中心設計

來自:從此啟程

鏈接:http://www.cnblogs.com/fancunwei/p/9612567.html


前言


說起支付平臺,支付寶量級的支付平臺和一個小型公司的支付不可同日耳語。一個初創或剛創業一兩年的公司,一沒人力,二沒財力的情況下,如果也想對接支付那怎麼辦呢?

感謝支付寶和微信支付,兩大行業巨頭提供了簡單易用的方案,簡化了對接流程,又能支持大部分銀行。今天我們就來根據不同業務規模,設計一個能經受業務考驗的支付平臺。

第一階段


舉個例子,阿力空閑時間,接了個外包的分銷系統。業務模型如:成為會員,可以自動帶二維碼的分銷海報,掃描你二維碼的人成為會員後,你獲得提成。

這個例子有幾個核心步驟:

申請會員,支付成為會員,自動生成海報,

計算分銷提成。

有點小挑戰的自動生成海報。這個可以參考微信引數二維碼接口和GDI+繪製圖片來搞定,利用html5的canvas也能搞定。

最核心的部分,當然是支付。

先來一張訂單表流程圖壓壓場面。

訂單模型

前些天看領域驅動提到了核心域和子域,那麼整個交易流程是是這個模型的核心域,訂單表是交易流程的子域。

我大概說下這些欄位,業務型別和業務id以及業務處理url實現了各個業務的解藕,各個業務線都有自己的限界背景關係。它可以根據取消日期和取消地址完成訂單的取消動作,可以根據支付平臺交易id和支付平臺查詢對賬。

業務通知狀態是用來綜述通知業務處理是否成功。說完了訂單,讓我們來看下整體交易流程。

交易流程

訂單有三個主流程,提交訂單是用戶主動觸發,支付回呼是屬於支付平臺觸發,定時取消是後臺任務根據設定的取消時間自動運行,小業務可以不考慮訂單取消問題。

這樣來說,第一版支付中心就完成了。由於剛上線,流量每天很少,平穩了運行一段時間後,也許會出現支付平臺支付,但搭建的支付中心卻未支付,只能手動修改資料庫了,並觸發業務回呼了,這在最終一致性里,可以成為人工補償。

後來不厭其煩,加了個支付日誌,記錄任何與支付平臺交互的信息,然後每隔一段時間掃描最近變更的日誌表,並和訂單表對比,發現不匹配的,修複為已支付,完美的解決了這個問題,這在最終一致性里,可概括為定時補償。

交易日誌表

老闆缺少人手,業務量又上升,又對阿力解決問題的能力很欣賞,就直接把阿力工資翻倍從原公司挖了過來。(故事純屬虛構)

第二階段


剛過來新公司不久,就接到了一筆融資,然後新公司擴招了很多同事,市場銷售人一多,產品線更多,線上支付流量也加快起來。阿力信心滿滿,覺得很有幹勁。

得意不久,就遇到了服務線反饋的問題:有客戶重覆支付,需要退款。於是改訂單,清理資料,財務退款,臨時解決了問題。後來次數多了,手工處理及易出錯,就查詢支付寶和微信的自動退款接口,然後依賴日誌表記錄過支付成功對比判定重覆支付,發起退款,引入了自動退款流程。

交易流程補充自動退款流程

然後又接到了一個線上客戶需要搶購的需求,每月有一天集中一起搶,類似小米秒殺那樣。然後到了激動的那天,系統撐過了三分鐘,華麗麗的掛了!熬了二十分鐘才恢復正常。

痛定思通,支付中心進入重構優化階段。由於公司人員擴張,有時間和精力和能力去重購優化更健康的業務架構。

一、引入訊息佇列Rabbitmq支撐流量削峰。如支付回呼先進訊息佇列,由訊息佇列去通知業務。大幅度縮短單次請求處理時間,提升兵法能力。

二、全面引入Redis快取,減小資料庫訪問壓力,部分關鍵業務表啟用HttpRuntime快取,性能指數級提升。

三、引入專業調度工具quartz.net或hangfire。可以用來處理定時查詢訂單交易問題,及退費問題。

四、購買商業.net監控平臺,如聽雲。檢測程式性能。

阿力跟隨新公司技術體系,也對支付中心實現了升級。

支付平臺回呼通知後,先轉發到訊息佇列,由訊息佇列來通知業務處理,如失敗後延時轉發到訊息佇列繼續執行,最高重試5次,然後發短信或郵件通知責任人。

針對之前線上支付平臺和自建平臺不一致問題,利用hangfire調度機制定時每天晚上拉取一周資料和支付平臺核對。確保了兩個異構系統的一致性。

為防止支付平臺同時通知,造成兩條支付日誌,先更新訂單成功後,在佇列里,用redis的incr和decr原子性操作,來確保只能同時操作一個訂單,另一個通知延遲處理。

資料庫開啟讀寫分離,部署集群。

經過阿力和同事們兩個月的協力合作與加班加點,新系統終於在那個客戶第三次線上搶購前一段時間上線。經過線上搶購驗證,新的系統輕輕鬆松的抗過了搶購,大家一片歡聲笑語。阿力看到十幾分鐘XX百萬的交易額驚獃了!,這真是金牌客戶啊!

到了年底,微信紅包火熱起來,許多客戶申請開通微信紅包,有家客戶粉絲有二十多萬,發的錢也特別多。當時一到點,十萬人齊刷刷搖手機搶紅包。

最後,重啟了幾遍應用程式池也不頂用。針對如此的流量,我們應該怎麼辦呢?每秒萬級的請求暫時就不是小公司處理的來的,況且這流量就過年才有,像級了春運。人有那麼多,搶到紅包的人是有限的。

百分之九十五的人都是無效流量。那就取巧吧,隨機抽取一部分人的資料進入服務器,其他的人就本地留存吧,通過這種思路減少了一大部分流量。

只考慮第一,第二階段的話,上面關於支付中心的思考架構是完全可以滿足交易量的。況且又有多少公司能邁向獨角獸之路呢?

念天地之悠悠,獨愴然而淚下!

第三階段

上面那種方式雖然取巧,針對特定業務,本來就是搶紅包,大部分人都是無效的,能說的過去,假如是主業務流程有萬級每秒甚至百萬千萬級每秒的請求量應該怎麼辦呢?阿力陷入了迷茫。

聽說過docker,kuberneters為代表的容器編排,聽說過CI/CD自動部署,聽說過微服務的強大,聽說過負載均衡,仿佛都是方向。

大海跨不過陸地,颱風卻能輕易穿梭,大化為小,繁化為簡,聚簡成面,規模化微服務也許才是解決巨量請求之道!(故事純屬虛構,不要代號入座)

附錄:最終一致性


說完瞭解決中小型流量的問題,我們來瞭解下一致性問題。

1、關係型資料庫事務追求ACID:

A:Atomicity,原子性

C:Consistency,一致性

I:Isolation,隔離性

D:Durability,持久性

2、CAP(帽子理論)

C:Consistency,一致性, 資料一致更新,所有資料變動都是同步的

A:Availability,可用性, 好的響應性能,完全的可用性指的是在任何故障模型下,服務都會在有限的時間處理響應

P:Partition tolerance,分割槽容錯性,可靠性

帽子理論證明,任何分佈式系統只可同時滿足二點,沒法三者兼顧

3、Base模型:

BA:Basically Available,基本可用

S:Soft State,軟狀態,狀態可以有一段時間不同步

E:Eventually Consistent,最終一致,最終資料是一致的就可以了,而不是時時保持強一致

利用查詢樣式,補償樣式,異步確保樣式,定時校對樣式等可實現分佈式系統最終一致性。

最終一致性更詳細用法參考李艷鵬老師關於分佈式一致性的講解。

https://www.jianshu.com/p/1156151e20c8?from=singlemessage&isappinstalled;=0

後言


阿力解決了支付中心的穩定問題後,就買了許多書,看到了上面關於最終一致性的陳述時,心裡想到,這些都是我已經實現了的,原來還有這麼多頭頭道道??

阿力又看到了領域驅動設計等書,感慨:支付領域模型真是學習領域驅動設計的最好實踐。它具有獨立的限界背景關係,通過回呼url和其他業務限界背景關係溝通。

最後再用交易流程在做個總結吧!

交易流程

關鍵點:

1、回呼部分,有訊息佇列通知,並支持失敗重試。

2、每天晚上定時拉取支付平臺物件記錄核賬,保證最終一致性。

3、支付平臺回呼時,根據支付日誌判定是否重覆支付,重覆支付的發起自動退款。

原始碼


計劃用.NET Core 按領域驅動的方式,完成以上設計。日期未定。



●編號149,輸入編號直達本文

●輸入m獲取文章目錄

推薦↓↓↓

Web開發

更多推薦18個技術類公眾微信

涵蓋:程式人生、演算法與資料結構、黑客技術與網絡安全、大資料技術、前端開發、Java、Python、Web開發、安卓開發、iOS開發、C/C++、.NET、Linux、資料庫、運維等。

赞(0)

分享創造快樂