金融魔方CTO解讀雲紅包背後的設計思路

紅包這一IT產品自2014年微信支付首發之後,就迅速火遍社交圈,已經成爲社交類,IM類,甚至電商類軟件不可或缺的功能之一。紅包市場需求如此廣闊,當前除了微信紅包,支付寶紅包以外,還有多家第三方廠商的紅包產品參與着垂直行業和細分市場的競爭,金融魔方雲紅包是其中之一。

金融魔方雲紅包面向IM類場景和電商場景分別推出了社交紅包和運營紅包兩類產品,其中社交羣紅包就直面最典型的高併發高可用的應用需求,金融魔方在長期地商戶考察和產品運維迭代中,總結了大量雲紅包的產品架構設計經驗,特在此爲技術討論提供一點微薄的案例,以此拋磚引玉,希望跟技術專家做更深入的交流。

業務場景

首先典型的羣紅包基本收發場景如下圖:

金融魔方CTO解讀雲紅包背後的設計思路

以上業務場景不算複雜,部分需求補充如下:

  1. 用戶發送紅包時指定該紅包可被分領的份數,紅包總額應該可按該份數分配,最少的一份至少可爲1分。爲兼顧公平和趣味性,每份紅包分配數額可按一個幸運因子n隨機劃分,該因子意味着保障最大份紅包金額不應超過所有份紅包平均金額的n倍,1<=n<=max(1.3,份額/x),x爲允許單個用戶最多可得到紅包總額的佔比,可以根據商戶需求設定。

  2. 一個紅包只能被同一個用戶搶取一次,羣紅包產品中,發包用戶可以參與紅包搶領。

產品聯動

以上紅包的需求雖然不多,但經過分析各式各樣的商戶定製化需求,我們最終得到的產品聯動圖是如下形式的:
金融魔方CTO解讀雲紅包背後的設計思路

解釋一下,這其實是三個產品聯動共同實現了紅包業務。

首先,紅包的入金實際上是一筆收銀臺的下單支付,紅包支付,既可以使用用戶賬戶的現有餘額,又可以直接通過第三方支付平臺進行銀行卡支付。值得注意的是,紅包支付生成之後,其實就隱含了一個紅包的臨時賬戶,這個賬戶記錄了資金從用戶賬戶轉出,尚未被用戶領取或退回時的中間態金額。

其後,紅包的發送和搶取是紅包產品專有的業務處理,這個業務處理流程才真正需要解決高併發並可用和最終一致性的問題。

之後,領取的紅包通過賬戶中心的轉賬接口,從臨時賬戶轉入領取用戶的錢包餘額賬戶,實現到賬,或通過收銀臺的退款接口,將超時未領取金額退回用戶支付通道(如支付通道不支持部分退款需轉而充值進入餘額)。

最後,用戶錢包的餘額可由用戶通過自主提現,回到綁定的銀行卡。

爲什麼原本簡單的一個業務場景我們要生生拆解成三個產品做複雜調用呢?因爲在我們爲客戶做的大量定製化需求中,發現有的客戶需要我們完整組合好的三個產品;有的已有了自己的收銀入金通道,只需要我們提供紅包和錢包;有的已有自己的錢包賬戶體系,但缺乏收銀臺和紅包;還有的,收銀臺和錢包賬戶都已具備,只缺少紅包。

因此,在做了高度的產品業務抽象之後,我們梳理設計出高內聚低耦合的三個獨立產品,可通過排列組合,可快速適配各種客戶需求,通過適配器模式兼容協同客戶各種現有職能系統。

應對考驗

通過以上分析我們知道,在紅包發送之前與領入之後,其實都已脫離了高併發場景,只有紅包產品的發領環節,才需要經歷單秒內成百上千的併發壓力,還要保證核心業務的一致性,多個羣組多個紅包,更是讓這種壓力可能成倍放大,對程序設計是極大的考驗,那我們是怎麼做的呢?

利用Redis設置分佈式鎖

首先我們通過redis爲用戶每一次請求申請了一個樂觀鎖,保證即使在異常情況下(客戶端已做限制)一個用戶其同時只可能有一個請求訪問領取紅包接口。

在一個用戶領取紅包成功後,將同步設置以其用戶ID和紅包ID的鍵值的紅包領取信息進入redis;在一個用戶領取紅包之前,也將判定是否redis中具有其用戶ID和紅包ID組成的鍵值,若存在,則表明其已領取過,不可再領取。

利用Redis作爲緩存

在生成紅包成功之時,就將其發包人,祝福語,總額,份數等惰性信息設置於redis中,並同步生成按紅包份數和幸運因子劃分的每份金額,並將其作爲List設置於redis中,。這樣避免每次搶取時再實時計算造成的領取與領取之間長時間互斥。只需要從Redis中能成功獲取到List中的一份數據,即可表示搶取成功。

同時,搶取的用戶和金額同步設置於redis作爲緩存以備實時查詢。

異步同步數據庫和賬戶

由於羣紅包領取場景中,用戶關注點着重在於搶到紅包的體驗,而後纔可能會轉到錢包賬戶查看餘額增減,因此紅包領取記錄的寫入數據庫,以及紅包領取進一步更新錢包賬戶的餘額,可以通過異步消息觸發實施,提供弱一致性體驗。

但基於任何環節都可能出錯這一分佈式架構的基本意識裏,對於這個保存領取信息的環節,一旦異步消息未能成功寫入消息隊列(消息隊列中間件崩潰等),馬上就要實施降級B方案,調用同步接口完成數據的同步,若B方案失敗,則實現C方案需將完整領取信息寫入本地日誌文件,待後續排除異常後,進行數據分析進行交易補償。當然,具有着三重方案後,已盡最大程度保障了交易數據的完整性。

投入實踐

在實施過程中,對於魔方自己的三類產品之間組合交易的相互調用,藉助底層的賬戶中心的轉賬等原子化交易,我們通常可以通過本地化事務保障最後紅包領取明細生成,餘額變更等業務的原子性和一致性。但在與客戶遺留系統對接的過程中,由於垂直化的微服務架構,我們往往需要藉助狀態查詢交易和異步補償流程去保障各系統業務記錄的最終一致性。

這就需要加入對賬與核賬流程。

對賬需保障紅包明細的入金和收銀臺的支付訂單記錄相符,紅包的分領需要和錢包賬戶中心的轉賬記錄相符,紅包的失效退餘需要與收銀臺的退款訂單記錄相符。

核賬需要保障在一個紅包的生命週期內,其收支最後歸0,在一個記賬日內的其所有紅包(已生成算)收支最後歸0(跨切日紅包T+1覈算時歸入上日差額)。

安全保障

由於紅包業務本身具有資金收益性,所以安全性也被關注,其中防止被外掛盜搶是很剛需的要求。魔方雲紅包採用以下兩種措施對外掛進行打擊:

  1. 產生紅包時,可同步傳送參數羣組成員ID集,後續所有可領取紅包的用戶ID必須在該集內纔可領取紅包。

  2. 通過對紅包用戶領取記錄和日誌的準實時分析,通過多維度的規則判定,可根據外掛賬號明顯異於人類操作的表現,篩查出可疑賬號,提供給客戶進行告警和處理。

以上,是魔方雲紅包實現方案的簡單介紹,隨着業務發展,業務場景和用戶習慣的變遷,魔方雲紅包產品還將做不斷的迭代和優化,以求爲用戶提供更好的體驗,爲客戶創造更大的價值。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章