社交軟件紅包技術(shù)解密(四):微信紅包系統(tǒng)是如何應(yīng)對高并發(fā)的
Posted on 2025-01-13 11:39 Jack Jiang 閱讀(136) 評論(0) 編輯 收藏本文來自微信團隊工程師方樂明的技術(shù)分享,由InfoQ編輯發(fā)布,下文收錄時有修訂和改動。
一、引言
每年節(jié)假日,微信紅包的收發(fā)數(shù)量都會暴漲,尤以除夕為最。如此大規(guī)模、高峰值的業(yè)務(wù)需要,背后需要怎樣的技術(shù)支撐?百億級別的紅包規(guī)模,如何保證并發(fā)性能與資金安全?
本文將為讀者介紹微信百億級別紅包背后的高并發(fā)設(shè)計實踐,內(nèi)容包括微信紅包系統(tǒng)的技術(shù)難點、解決高并發(fā)問題通常使用的方案,以及微信紅包系統(tǒng)的所采用高并發(fā)解決方案。
技術(shù)交流:
- 移動端IM開發(fā)入門文章:《新手入門一篇就夠:從零開發(fā)移動端IM》
- 開源IM框架源碼:https://github.com/JackJiang2011/MobileIMSDK(備用地址點此)
二、分享者
方樂明:現(xiàn)任微信支付應(yīng)用產(chǎn)品系統(tǒng)負責人,主要從事微信紅包、微信轉(zhuǎn)賬、微信群收款等支付應(yīng)用產(chǎn)品的系統(tǒng)設(shè)計、可用性提升、高性能解決方案設(shè)計等,曾連續(xù)多年負責春節(jié)微信紅包系統(tǒng)的性能優(yōu)化與穩(wěn)定性提升,取得良好的效果。
三、系列文章
? 系列文章目錄:
- 《社交軟件紅包技術(shù)解密(一):全面解密QQ紅包技術(shù)方案——架構(gòu)、技術(shù)實現(xiàn)等》
- 《社交軟件紅包技術(shù)解密(二):解密微信搖一搖紅包從0到1的技術(shù)演進》
- 《社交軟件紅包技術(shù)解密(三):微信搖一搖紅包雨背后的技術(shù)細節(jié)》
- 《社交軟件紅包技術(shù)解密(四):微信紅包系統(tǒng)是如何應(yīng)對高并發(fā)的》(* 本文)
- 《社交軟件紅包技術(shù)解密(五):微信紅包系統(tǒng)是如何實現(xiàn)高可用性的》
- 《社交軟件紅包技術(shù)解密(六):微信紅包系統(tǒng)的存儲層架構(gòu)演進實踐》
- 《社交軟件紅包技術(shù)解密(七):支付寶紅包的海量高并發(fā)技術(shù)實踐》
- 《社交軟件紅包技術(shù)解密(八):全面解密微博紅包技術(shù)方案》
- 《社交軟件紅包技術(shù)解密(九):談?wù)勈諵春節(jié)紅包的設(shè)計、容災(zāi)、運維、架構(gòu)等》
- 《社交軟件紅包技術(shù)解密(十):手Q客戶端針對2020年春節(jié)紅包的技術(shù)實踐》
- 《社交軟件紅包技術(shù)解密(十一):最全解密微信紅包隨機算法(含演示代碼)》
- 《社交軟件紅包技術(shù)解密(十二):解密抖音春節(jié)紅包背后的技術(shù)設(shè)計與實踐》
- 《社交軟件紅包技術(shù)解密(十三):微信團隊首次揭秘微信紅包算法,為何你搶到的是0.01元》
? 其它相關(guān)文章:
- 《技術(shù)往事:“QQ群”和“微信紅包”是怎么來的?》
- 《QQ 18年:解密8億月活的QQ后臺服務(wù)接口隔離技術(shù)》
- 《月活8.89億的超級IM微信是如何進行Android端兼容測試的》
- 《開源libco庫:單機千萬連接、支撐微信8億用戶的后臺框架基石 [源碼下載]》
- 《微信技術(shù)總監(jiān)談架構(gòu):微信之道——大道至簡(演講全文)》
- 《微信技術(shù)總監(jiān)談架構(gòu):微信之道——大道至簡(PPT講稿) [附件下載]》
- 《如何解讀《微信技術(shù)總監(jiān)談架構(gòu):微信之道——大道至簡》》
- 《微信海量用戶背后的后臺系統(tǒng)存儲架構(gòu)(視頻+PPT) [附件下載]》
- 《微信異步化改造實踐:8億月活、單機千萬連接背后的后臺解決方案》
- 《微信朋友圈海量技術(shù)之道PPT [附件下載]》
- 《架構(gòu)之道:3個程序員成就微信朋友圈日均10億發(fā)布量[有視頻]》
- 《快速裂變:見證微信強大后臺架構(gòu)從0到1的演進歷程(一)》
- 《快速裂變:見證微信強大后臺架構(gòu)從0到1的演進歷程(二)》
- 《微信“紅包照片”背后的技術(shù)難題》
- 《微信技術(shù)分享:微信的海量IM聊天消息序列號生成實踐(算法原理篇)》
- 《微信技術(shù)分享:微信的海量IM聊天消息序列號生成實踐(容災(zāi)方案篇)》
四、微信紅包的兩大業(yè)務(wù)特點
微信紅包(尤其是發(fā)在微信群里的紅包,即群紅包),業(yè)務(wù)形態(tài)上很類似網(wǎng)上的普通商品“秒殺”活動。
就像下面這樣:
- 1)用戶在微信群里發(fā)一個紅包,等同于是普通商品“秒殺”活動的商品上架;
- 2)微信群里的所有用戶搶紅包的動作,等同于“秒殺”活動中的查詢庫存;
- 3)用戶搶到紅包后拆紅包的動作,則對應(yīng)“秒殺”活動中用戶的“秒殺”動作。
不過除了上面的相同點之外,微信紅包在業(yè)務(wù)形態(tài)上與普通商品“秒殺”活動相比,還具備自身的特點。
首先:微信紅包業(yè)務(wù)比普通商品“秒殺”有更海量的并發(fā)要求。
微信紅包用戶在微信群里發(fā)一個紅包,等同于在網(wǎng)上發(fā)布一次商品“秒殺”活動。假設(shè)同一時間有 10 萬個群里的用戶同時在發(fā)紅包,那就相當于同一時間有 10 萬個“秒殺”活動發(fā)布出去。10 萬個微信群里的用戶同時搶紅包,將產(chǎn)生海量的并發(fā)請求。
其次:微信紅包業(yè)務(wù)要求更嚴格的安全級別。
微信紅包業(yè)務(wù)本質(zhì)上是資金交易。微信紅包是微信支付的一個商戶,提供資金流轉(zhuǎn)服務(wù)。
用戶發(fā)紅包時,相當于在微信紅包這個商戶上使用微信支付購買一筆“錢”,并且收貨地址是微信群。當用戶支付成功后,紅包“發(fā)貨”到微信群里,群里的用戶拆開紅包后,微信紅包提供了將“錢”轉(zhuǎn)入折紅包用戶微信零錢的服務(wù)。
資金交易業(yè)務(wù)比普通商品“秒殺”活動有更高的安全級別要求。普通的商品“秒殺”商品由商戶提供,庫存是商戶預(yù)設(shè)的,“秒殺”時可以允許存在“超賣”(即實際被搶的商品數(shù)量比計劃的庫存多)、“少賣”(即實際被搶的商戶數(shù)量比計劃的庫存少)的情況。但是對于微信紅包,用戶發(fā) 100 元的紅包絕對不可以被拆出 101 元;用戶發(fā) 100 元只被領(lǐng)取 99 元時,剩下的 1 元在 24 小時過期后要精確地退還給發(fā)紅包用戶,不能多也不能少。
以上是微信紅包業(yè)務(wù)模型上的兩大特點。
五、 微信紅包系統(tǒng)的技術(shù)難點
在介紹微信紅包系統(tǒng)的技術(shù)難點之前,先介紹下簡單的、典型的商品“秒殺”系統(tǒng)的架構(gòu)設(shè)計,如下圖所示。

該系統(tǒng)由接入層、邏輯服務(wù)層、存儲層與緩存構(gòu)成:
- 1)Proxy 處理請求接入;
- 2)Server 承載主要的業(yè)務(wù)邏輯;
- 3)Cache 用于緩存庫存數(shù)量;
- 4)DB 則用于數(shù)據(jù)持久化。
一個“秒殺”活動,對應(yīng) DB 中的一條庫存記錄。當用戶進行商品“秒殺”時,系統(tǒng)的主要邏輯在于 DB 中庫存的操作上。
一般來說,對 DB 的操作流程有以下三步:
- 1)鎖庫存;
- 2)插入“秒殺”記錄;
- 3)更新庫存。
其中,鎖庫存是為了避免并發(fā)請求時出現(xiàn)“超賣”情況。同時要求這三步操作需要在一個事務(wù)中完成(所謂的事務(wù),是指作為單個邏輯工作單元執(zhí)行的一系列操作,要么完全地執(zhí)行,要么完全地不執(zhí)行)。
“秒殺”系統(tǒng)的設(shè)計難點就在這個事務(wù)操作上。商品庫存在 DB 中記為一行,大量用戶同時“秒殺”同一商品時,第一個到達 DB 的請求鎖住了這行庫存記錄。在第一個事務(wù)完成提交之前這個鎖一直被第一個請求占用,后面的所有請求需要排隊等待。同時參與“秒殺”的用戶越多,并發(fā)進 DB 的請求越多,請求排隊越嚴重。因此,并發(fā)請求搶鎖,是典型的商品“秒殺”系統(tǒng)的設(shè)計難點。
微信紅包業(yè)務(wù)相比普通商品“秒殺”活動,具有海量并發(fā)、高安全級別要求的特點。
在微信紅包系統(tǒng)的設(shè)計上,除了并發(fā)請求搶鎖之外,還有以下兩個突出難點:
首先,事務(wù)級操作量級大:
上文介紹微信紅包業(yè)務(wù)特點時提到,普遍情況下同時會有數(shù)以萬計的微信群在發(fā)紅包。這個業(yè)務(wù)特點映射到微信紅包系統(tǒng)設(shè)計上,就是有數(shù)以萬計的“并發(fā)請求搶鎖”同時在進行。這使得 DB 的壓力比普通單個商品“庫存”被鎖要大很多倍;
其次,事務(wù)性要求嚴格:
微信紅包系統(tǒng)本質(zhì)上是一個資金交易系統(tǒng),相比普通商品“秒殺”系統(tǒng)有更高的事務(wù)級別要求。
六、解決高并發(fā)問題通常使用的方案
普通商品“秒殺”活動系統(tǒng),解決高并發(fā)問題的方案,大體有以下幾種。
6.1方案一:使用內(nèi)存操作替代實時的 DB 事務(wù)操作
如圖 2 所示,將“實時扣庫存”的行為上移到內(nèi)存 Cache 中操作,內(nèi)存 Cache 操作成功直接給 Server 返回成功,然后異步落 DB 持久化。

這個方案的優(yōu)點是用內(nèi)存操作替代磁盤操作,提高了并發(fā)性能。
但是缺點也很明顯,在內(nèi)存操作成功但 DB 持久化失敗,或者內(nèi)存 Cache 故障的情況下,DB 持久化會丟數(shù)據(jù),不適合微信紅包這種資金交易系統(tǒng)。
6.2方案二:使用樂觀鎖替代悲觀鎖
所謂悲觀鎖,是關(guān)系數(shù)據(jù)庫管理系統(tǒng)里的一種并發(fā)控制的方法。它可以阻止一個事務(wù)以影響其他用戶的方式來修改數(shù)據(jù)。如果一個事務(wù)執(zhí)行的操作對某行數(shù)據(jù)應(yīng)用了鎖,那只有當這個事務(wù)把鎖釋放,其他事務(wù)才能夠執(zhí)行與該鎖沖突的操作。對應(yīng)于上文分析中的“并發(fā)請求搶鎖”行為。
所謂樂觀鎖,它假設(shè)多用戶并發(fā)的事務(wù)在處理時不會彼此互相影響,各事務(wù)能夠在不產(chǎn)生鎖的情況下處理各自影響的那部分數(shù)據(jù)。在提交數(shù)據(jù)更新之前,每個事務(wù)會先檢查在該事務(wù)讀取數(shù)據(jù)后,有沒有其他事務(wù)又修改了該數(shù)據(jù)。如果其他事務(wù)有更新的話,正在提交的事務(wù)會進行回滾。
商品“秒殺”系統(tǒng)中,樂觀鎖的具體應(yīng)用方法,是在 DB 的“庫存”記錄中維護一個版本號。在更新“庫存”的操作進行前,先去 DB 獲取當前版本號。在更新庫存的事務(wù)提交時,檢查該版本號是否已被其他事務(wù)修改。如果版本沒被修改,則提交事務(wù),且版本號加 1;如果版本號已經(jīng)被其他事務(wù)修改,則回滾事務(wù),并給上層報錯。
這個方案解決了“并發(fā)請求搶鎖”的問題,可以提高 DB 的并發(fā)處理能力。
但是如果應(yīng)用于微信紅包系統(tǒng),則會存在下面三個問題:
- 1)如果拆紅包采用樂觀鎖:那么在并發(fā)搶到相同版本號的拆紅包請求中,只有一個能拆紅包成功,其他的請求將事務(wù)回滾并返回失敗,給用戶報錯,用戶體驗完全不可接受;
- 2)如果采用樂觀鎖:將會導(dǎo)致第一時間同時拆紅包的用戶有一部分直接返回失敗,反而那些“手慢”的用戶,有可能因為并發(fā)減小后拆紅包成功,這會帶來用戶體驗上的負面影響;
- 3)如果采用樂觀鎖的方式:會帶來大數(shù)量的無效更新請求、事務(wù)回滾,給 DB 造成不必要的額外壓力。
基于以上原因,微信紅包系統(tǒng)不能采用樂觀鎖的方式解決并發(fā)搶鎖問題。
七、微信紅包系統(tǒng)的高并發(fā)解決方案
綜合上面的分析,微信紅包系統(tǒng)針對相應(yīng)的技術(shù)難點,采用了下面幾個方案,解決高并發(fā)問題。
7.1系統(tǒng)垂直 SET 化,分而治之
微信紅包用戶發(fā)一個紅包時,微信紅包系統(tǒng)生成一個 ID 作為這個紅包的唯一標識。接下來這個紅包的所有發(fā)紅包、搶紅包、拆紅包、查詢紅包詳情等操作,都根據(jù)這個 ID 關(guān)聯(lián)。
紅包系統(tǒng)根據(jù)這個紅包 ID,按一定的規(guī)則(如按 ID 尾號取模等),垂直上下切分。切分后,一個垂直鏈條上的邏輯 Server 服務(wù)器、DB 統(tǒng)稱為一個 SET。
各個 SET 之間相互獨立,互相解耦。并且同一個紅包 ID 的所有請求,包括發(fā)紅包、搶紅包、拆紅包、查詳情詳情等,垂直 stick 到同一個 SET 內(nèi)處理,高度內(nèi)聚。通過這樣的方式,系統(tǒng)將所有紅包請求這個巨大的洪流分散為多股小流,互不影響,分而治之,如下圖所示。

這個方案解決了同時存在海量事務(wù)級操作的問題,將海量化為小量。
7.2邏輯 Server 層將請求排隊,解決 DB 并發(fā)問題
紅包系統(tǒng)是資金交易系統(tǒng),DB 操作的事務(wù)性無法避免,所以會存在“并發(fā)搶鎖”問題。但是如果到達 DB 的事務(wù)操作(也即拆紅包行為)不是并發(fā)的,而是串行的,就不會存在“并發(fā)搶鎖”的問題了。
按這個思路,為了使拆紅包的事務(wù)操作串行地進入 DB,只需要將請求在 Server 層以 FIFO(先進先出)的方式排隊,就可以達到這個效果。從而問題就集中到 Server 的 FIFO 隊列設(shè)計上。
微信紅包系統(tǒng)設(shè)計了分布式的、輕巧的、靈活的 FIFO 隊列方案。其具體實現(xiàn)如下:
首先,將同一個紅包 ID 的所有請求 stick 到同一臺 Server。
上面 SET 化方案已經(jīng)介紹,同個紅包 ID 的所有請求,按紅包 ID stick 到同個 SET 中。不過在同個 SET 中,會存在多臺 Server 服務(wù)器同時連接同一臺 DB(基于容災(zāi)、性能考慮,需要多臺 Server 互備、均衡壓力)。
為了使同一個紅包 ID 的所有請求,stick 到同一臺 Server 服務(wù)器上,在 SET 化的設(shè)計之外,微信紅包系統(tǒng)添加了一層基于紅包 ID hash 值的分流,如下圖所示。

其次,設(shè)計單機請求排隊方案。
將 stick 到同一臺 Server 上的所有請求在被接收進程接收后,按紅包 ID 進行排隊。然后串行地進入 worker 進程(執(zhí)行業(yè)務(wù)邏輯)進行處理,從而達到排隊的效果,如下圖所示。

最后,增加 memcached 控制并發(fā)。
為了防止 Server 中的請求隊列過載導(dǎo)致隊列被降級,從而所有請求擁進 DB,系統(tǒng)增加了與 Server 服務(wù)器同機部署的 memcached,用于控制拆同一個紅包的請求并發(fā)數(shù)。
具體來說,利用 memcached 的 CAS 原子累增操作,控制同時進入 DB 執(zhí)行拆紅包事務(wù)的請求數(shù),超過預(yù)先設(shè)定數(shù)值則直接拒絕服務(wù)。用于 DB 負載升高時的降級體驗。
通過以上三個措施,系統(tǒng)有效地控制了 DB 的“并發(fā)搶鎖”情況。
7.3雙維度庫表設(shè)計,保障系統(tǒng)性能穩(wěn)定
紅包系統(tǒng)的分庫表規(guī)則,初期是根據(jù)紅包 ID 的 hash 值分為多庫多表。隨著紅包數(shù)據(jù)量逐漸增大,單表數(shù)據(jù)量也逐漸增加。而 DB 的性能與單表數(shù)據(jù)量有一定相關(guān)性。當單表數(shù)據(jù)量達到一定程度時,DB 性能會有大幅度下降,影響系統(tǒng)性能穩(wěn)定性。采用冷熱分離,將歷史冷數(shù)據(jù)與當前熱數(shù)據(jù)分開存儲,可以解決這個問題。
處理微信紅包數(shù)據(jù)的冷熱分離時,系統(tǒng)在以紅包 ID 維度分庫表的基礎(chǔ)上,增加了以循環(huán)天分表的維度,形成了雙維度分庫表的特色。
具體來說,就是分庫表規(guī)則像 db_xx.t_y_dd 設(shè)計,其中,xx/y 是紅包 ID 的 hash 值后三位,dd 的取值范圍在 01~31,代表一個月天數(shù)最多 31 天。
通過這種雙維度分庫表方式,解決了 DB 單表數(shù)據(jù)量膨脹導(dǎo)致性能下降的問題,保障了系統(tǒng)性能的穩(wěn)定性。同時,在熱冷分離的問題上,又使得數(shù)據(jù)搬遷變得簡單而優(yōu)雅。
綜上所述:微信紅包系統(tǒng)在解決高并發(fā)問題上的設(shè)計,主要采用了 SET 化分治、請求排隊、雙維度分庫表等方案,使得單組 DB 的并發(fā)性能提升了 8 倍左右,取得了很好的效果。
八、本文小結(jié)
微信紅包系統(tǒng)是一個高并發(fā)的資金交易系統(tǒng),最大的技術(shù)挑戰(zhàn)是保障并發(fā)性能與資金安全。
這種全新的技術(shù)挑戰(zhàn),傳統(tǒng)的“秒殺”系統(tǒng)設(shè)計方案已不能完全解決。在分析了業(yè)界“秒殺”系統(tǒng)解決方案的基礎(chǔ)上,微信紅包采用了 SET 化、請求排隊串行化、雙維度分庫表等設(shè)計,形成了獨特的高并發(fā)、資金安全系統(tǒng)解決方案,并在平時節(jié)假日、春節(jié)紅包雨實踐中充分證明了可行性,取得了顯著的效果。以2017 雞年除夕夜為例,微信紅包收發(fā)峰值達到 76 萬每秒,收發(fā)微信紅包 142 億個,微信紅包系統(tǒng)的表現(xiàn)穩(wěn)定,實現(xiàn)了除夕夜系統(tǒng)零故障。
九、更多鵝廠技術(shù)文章匯總
《微信朋友圈千億訪問量背后的技術(shù)挑戰(zhàn)和實踐總結(jié)》
《騰訊技術(shù)分享:騰訊是如何大幅降低帶寬和網(wǎng)絡(luò)流量的(圖片壓縮篇)》
《騰訊技術(shù)分享:騰訊是如何大幅降低帶寬和網(wǎng)絡(luò)流量的(音視頻技術(shù)篇)》
《IM全文檢索技術(shù)專題(二):微信移動端的全文檢索多音字問題解決方案》
《騰訊技術(shù)分享:Android版手機QQ的緩存監(jiān)控與優(yōu)化實踐》
《微信團隊分享:iOS版微信的高性能通用key-value組件技術(shù)實踐》
《微信團隊分享:iOS版微信是如何防止特殊字符導(dǎo)致的炸群、APP崩潰的?》
《騰訊技術(shù)分享:Android手Q的線程死鎖監(jiān)控系統(tǒng)技術(shù)實踐》
《微信團隊原創(chuàng)分享:iOS版微信的內(nèi)存監(jiān)控系統(tǒng)技術(shù)實踐》
《讓互聯(lián)網(wǎng)更快:新一代QUIC協(xié)議在騰訊的技術(shù)實踐分享》
(本文已同步發(fā)布于:http://www.52im.net/thread-2548-1-1.html)
作者:Jack Jiang (點擊作者姓名進入Github)
出處:http://www.52im.net/space-uid-1.html
交流:歡迎加入即時通訊開發(fā)交流群 215891622
討論:http://www.52im.net/
Jack Jiang同時是【原創(chuàng)Java
Swing外觀工程BeautyEye】和【輕量級移動端即時通訊框架MobileIMSDK】的作者,可前往下載交流。
本博文
歡迎轉(zhuǎn)載,轉(zhuǎn)載請注明出處(也可前往 我的52im.net 找到我)。