揭秘微信紅包:架構、搶紅包演算法、高併發和降級方案

来源:http://www.cnblogs.com/8hao/archive/2016/04/12/5383143.html
-Advertisement-
Play Games

編者按 與傳統意義上的紅包相比,近兩年火起來的“紅包”,似乎才是如今春節的一大重頭戲。歷經上千年時代傳承與變遷,春節發紅包早已成為歷史沉澱的文化習俗,融入了民族的血脈。按照各家公佈的數據,除夕全天微信用戶紅包總發送量達到80.8億個,紅包峰值收發量為40.9萬個/秒。春晚直播期間討論春晚的微博達到5 ...


編者按

與傳統意義上的紅包相比,近兩年火起來的“紅包”,似乎才是如今春節的一大重頭戲。歷經上千年時代傳承與變遷,春節發紅包早已成為歷史沉澱的文化習俗,融入了民族的血脈。按照各家公佈的數據,除夕全天微信用戶紅包總發送量達到80.8億個,紅包峰值收發量為40.9萬個/秒。春晚直播期間討論春晚的微博達到5191萬條,網友互動量達到1.15億,網友搶微博紅包的總次數超過8億次。

為此,InfoQ策划了“春節紅包”系列文章,以期為讀者剖析各大平臺的紅包活動背後的技術細節。本文為微信篇。

微信紅包在經過15年春晚搖一搖之後,2015年上半年業務量一度呈指數級增長。尤其是微信紅包活躍用戶數的大量增長,使得2016除夕跨年紅包成為極大挑戰。為了應對16年春節可預知的紅包海量業務,紅包系統在架構上進行了一系列調整和優化。主要包括異地架構、cache系統優化、拆紅包併發策略優化、存儲優化一系列措施,為迎接2016春節紅包挑戰做好準備。 下麵介紹最主要的一些思路。

架構

微信用戶在國內有深圳、上海兩個接入點,習慣性稱之為南、北(即深圳為南,上海為北)。用戶請求接入後,不同業務根據業務特性選擇部署方式。微信紅包在信息流上可以分為訂單緯度與用戶緯度。其中訂單是貫穿紅包發、搶、拆、詳情列表等業務的關鍵信息,屬於交易類信息;而用戶緯度指的是紅包用戶的收紅包列表、發紅包列表,屬於展示類信息。紅包系統在架構上,有以下幾個方面:

南北分佈

1、訂單層南北獨立體系,數據不同步

用戶就近接入,請求發紅包時分配訂單南北,併在單號打上南北標識。搶紅包、拆紅包、查紅包詳情列表時,接入層根據紅包單號上的南北標識將流量分別引到南北系統閉環。根據發紅包用戶和搶紅包用戶的所屬地不同,有以下四種情況:

1) 深圳用戶發紅包,深圳用戶搶

訂單落在深圳,深圳用戶搶紅包時不需要跨城,在深圳完成閉環。

2) 深圳用戶發紅包,上海用戶搶

訂單落在深圳,上海用戶搶紅包,在上海接入後通過專線跨城到深圳,最後在深圳閉環完成搶紅包。

3) 上海用戶發紅包,上海用戶搶

訂單落在上海,上海用戶搶紅包時不需要跨城,在上海完成閉環。

4) 上海用戶發紅包,深圳用戶搶

訂單落在上海,深圳用戶搶紅包,從深圳接入後通過專線跨城到上海,最後在上海閉環完成搶紅包。

系統這樣設計,好處是南北系統分攤流量,降低系統風險。

2、用戶數據寫多讀少,全量存深圳,非同步隊列寫入,查時一邊跨城

用戶數據的查詢入口,在微信錢包中,隱藏的很深。這決定了用戶數據的訪問量不會太大,而且也被視為可旁路的非關鍵信息,實時性要求不高。因此,只需要在發紅包、拆紅包時,從訂單緯度拆分出用戶數據寫入請求,由MQ非同步寫入深圳。後臺將訂單與用戶進行定時對賬保證數據完整性即可。

3、支持南北流量靈活調控

紅包系統南北分佈後,訂單落地到深圳還是上海,是可以靈活分配的,只需要在接入層上做邏輯。例如,可以在接入層中,實現讓所有紅包請求,都落地到深圳(無論用戶從上海接入,還是深圳接入),這樣上海的紅包業務系統將不會有請求量。提升了紅包系統的容災能力。同時,實現了接入層上的後臺管理系統,實現了秒級容量調控能力。可根據南北請求量的實時監控,做出對應的調配。

4、DB故障時流量轉移能力
基於南北流量的調控能力,當發現DB故障時,可將紅包業務流量調到另外一邊,實現DB故障的容災。

預訂單

支付前訂單落cache,同時利用cache的原子incr操作順序生成紅包訂單號。優點是cache的輕量操作,以及減少DB廢單。在用戶請求發紅包與真正支付之間,存在一定的轉化率,部分用戶請求發紅包後,並不會真正去付款。

拆紅包入賬非同步化

信息流與資金流分離。拆紅包時,DB中記下拆紅包憑證,然後非同步隊列請求入賬。入賬失敗通過補償隊列補償,最終通過紅包憑證與用戶賬戶入賬流水對賬,保證最終一致性。

這個架構設計,理論基礎是快慢分離。紅包的入賬是一個分佈事務,屬於慢介面。而拆紅包憑證落地則速度快。實際應用場景中,用戶搶完紅包,只關心詳情列表中誰是“最佳手氣”,很少關心搶到的零是否已經到賬。因為只需要展示用戶的拆紅包憑證即可。

發拆落地,其他操作雙層cache

1、Cache住所有查詢,兩層cache

除了使用ckv做全量緩存,還在數據訪問層dao中增加本機記憶體cache做二級緩存,cache住所有讀請求。

查詢失敗或者查詢不存在時,降級記憶體cache;記憶體cache查詢失敗或記錄不存在時降級DB。

DB本身不做讀寫分離。

2、DB寫同步cache,容忍少量不一致
DB寫操作完成後,dao中同步記憶體cache,業務服務層同步ckv,失敗由非同步隊列補償,定時的ckv與DB備機對賬,保證最終數據一致。

高併發

微信紅包的併發挑戰,主要在於微信大群,多人同時搶同一個紅包。這種情況,存在競爭MySQL行鎖。為了控制這種併發,團隊做了以下一些事情:

1、請求按紅包訂單路由,邏輯塊垂直sticky,事務隔離

按紅包訂單劃分邏輯單元,單元內業務閉環。服務rpc調用時,使用紅包訂單號的hash值為key尋找下一跳地址。對同一個紅包的所有拆請求、查詢請求,都路由到同一臺邏輯機器、同一臺DB中處理。

2、Dao搭建本機Memcache記憶體cache,控制同一紅包併發個數

在DB的接入機dao中,搭建本機記憶體cache。以紅包訂單號為key,對同一個紅包的拆請求做原子計數,控制同一時刻能進DB中拆紅包的併發請求數。

這個策略的實施,依賴於請求路由按紅包訂單hash值走,確保同一紅包的所有請求路由到同一邏輯層機器。

3、多層級併發量控制
1) 發紅包控制

發紅包是業務流程的入口,控制了這裡的併發量,代表著控制了紅包業務整體的併發量。在發紅包的業務鏈路里,做了多層的流量控制,確保產生的有效紅包量級在可控範圍。

2) 搶紅包控制

微信紅包領取時分為兩個步驟,搶和拆。搶紅包這個動作本身就有控制拆併發的作用。因為搶紅包時,只需要查cache中的數據,不需要請求DB。對於紅包已經領完、用戶已經領過、紅包已經過期等流量可以直接攔截。而對於有資格進入拆紅包的請求量,也做流量控制。通過這些處理,最後可進入拆環節的流量大大減少,並且都是有效請求。

3) 拆時記憶體cache控制

針對同一個紅包併發拆的控制,上文已經介紹。

4、DB簡化和拆分

DB的併發能力,有很多影響因素。紅包系統結合紅包使用情境,進行了一些優化。比較有借鑒意義的,主要有以下兩點:

1) 訂單表只存關鍵欄位,其他欄位只在cache中存儲,可柔性。

紅包詳情的展示中,除了訂單關鍵信息(用戶、單號、金額、時間、狀態)外,還有用戶頭像、昵稱、祝福語等欄位。這些欄位對交易來說不是關鍵信息,卻占據大量的存儲空間。

將這些非關鍵信息拆出來,只存在cache,用戶查詢展示,而訂單中不落地。這樣可以維持訂單的輕量高效,同時cache不命中時,又可從實時介面中查詢補償,達到優化訂單DB容量的效果。

2) DB雙重緯度分庫表,冷熱分離

使用訂單hash、訂單日期,兩個緯度分庫表,也即db_xxx.t_x_dd這樣的格式。其中,x表示訂單hash值,dd表示01-31迴圈日。訂單hash緯度,是為了將訂單打散到不同的DB伺服器中,均衡壓力。訂單日期迴圈日緯度,是為了避免單表數據無限擴張,使每天都是一張空表。

另外,紅包的訂單訪問熱度,是非常典型的冷熱型。熱數據集中在一兩天內,且隨時間急劇消減。線上熱資料庫只需要存幾天的數據,其他數據可以定時移到成本低的冷資料庫中。迴圈日表也使得歷史數據的遷移變得方便。

紅包演算法

首先,如果紅包只有一個,本輪直接使用全部金額,確保紅包發完。

然後,計算出本輪紅包最少要領取多少,才能保證紅包領完,即本輪下水位;輪最多領取多少,才能保證每個人都領到,即本輪上水位。主要方式如下:

計算本輪紅包金額下水位:假設本輪領到最小值1分,那接下來每次都領到200元紅包能領完,那下水位為1分;如果不能領完,那按接下來每次都領200元,剩下的本輪應全部領走,是本輪的下水位。

計算本輪紅包上水位:假設本輪領200元,剩下的錢還足夠接下來每輪領1分錢,那本輪上水位為200元;如果已經不夠領,那按接下來每輪領1分,計算本輪的上水位。

為了使紅包金額不要太懸殊,使用紅包均值調整上水位。如果上水位金額大於兩倍紅包均值,那麼使用兩倍紅包均值作為上水位。換句話說,每一輪搶到的紅包金額,最高為兩倍剩下紅包的均值。

最後,獲取隨機數並用上水位取餘,如果結果比下水位還小,則直接使用下水位,否則使用隨機金額為本輪拆到金額。

柔性降級方案

系統到處存在發生異常的可能,需要對所有的環節做好應對的預案。下麵列舉微信紅包對系統異常的主要降級考慮。

1、 下單cache故障降級DB

下單cache有兩個作用,生成紅包訂單與訂單緩存。緩存故障情況下,降級為直接落地DB,並使用id生成器獨立生成訂單號。

2、 搶時cache故障降級DB

搶紅包時,查詢cache,攔截紅包已經搶完、用戶已經搶過、紅包已經過期等無效請求。當cache故障時,降級DB查詢,同時打開DB限流保護開關,防止DB壓力過大導致服務不可用。

另外,cache故障降級DB時,DB不存儲用戶頭像、用戶昵稱等(上文提到的優化),此時一併降級為實時介面查詢。查詢失敗,繼續降級為展示預設頭像與昵稱。

3、 拆時資金入賬多級柔性

拆紅包時,DB記錄拆紅包單據,然後執行資金轉賬。單據需要實時落地,而資金轉賬,這裡做了多個層級的柔性降級方案:

大額紅包實時轉賬,小額紅包入隊列非同步轉賬 所有紅包進隊列非同步轉賬 實時流程不執行轉賬,事後憑單據批量入賬。

總之,單據落地後,真實入賬可實時、可非同步,最終保證一致即可。

4、 用戶列表降級

用戶列表數據在微信紅包系統中,屬於非關鍵路徑信息,屬於可被降級部分。

首先,寫入時通過MQ非同步寫,通過定時對賬保證一致性。

其次,cache中只緩存兩屏,用戶查詢超過兩屏則查用戶列表DB。在系統壓力大的情況下,可以限制用戶只查兩屏。

調整後的系統經過了16年春節的實踐檢驗,平穩地度過了除夕業務高峰,保障了紅包用戶的體驗。

作者介紹

方樂明,2011年畢業於華南理工大學通信與信息系統專業,畢業後就職於財付通科技有限公司。微信支付團隊組建後,主要負責微信紅包、微信轉賬、AA收款等支付應用產品的後臺架構。

原文:http://www.infoq.com

http://cxy.liuzhihengseo.com/522.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Atitit.木馬病毒的操作註冊表原理 系統服務管理器 atiSysService 1. atiSysService1 2. atiSysService 原理1 3. Java code1 4. 參考5 1. atiSysService http://localhost:8080/regsitMan ...
  • /* * 功能:加深對事件處理機制的理解 * 1.通過控制上下左右鍵,來控制一個小球的位置 */package com.test1;import java.awt.*;import javax.swing.*;import java.awt.event.*; public class Demo9_4 ...
  • 在修改完善過程中博客園出現錯誤,誤刪。現在補上! 源代碼: 結果截圖: 整數部分: 分數部分: 結果分析:數據,消息都是通過通知框輸入輸出。 總結:還有功能尚未實現,而且實現的功能也不盡完美。 比如條件控制處不能夠產生負數,是利用暴力窮舉,而沒有特殊的辦法。 恢復內容結束 ...
  • Atitit.prototype-base class-based 基於“類” vs 基於“原型” 1. 基於“類” vs 基於“原型”1 2. 對象的產生有兩種基本方式。一種是以原型(prototype)對象為基礎產生新的對象。一種是以類(class)為基礎產生新對象1 3. 基於類(class- ...
  • Atitit.判斷漢字的編碼 regedit 註冊表裡面的reg_sz 1. 可以判斷出是unicode編碼1 2. 有下麵分割ucs2 大頭小偷編碼1 3. 使用小偷編碼測試1 4. 註冊表裡面的reg_dword讀取2 1. 可以判斷出是unicode編碼 byte[] ai={44, 103, ...
  • Atitit。Js調用後臺語言 java c# php swing android swt的方法大總結 1. Js調用後臺語言有三種方法1 2. Swt BrowserFunction 綁定方法1 3. Android webview 可以綁定對象1 4. Js 調用Java Nashorn引擎,可 ...
  • Atitit.vod 視頻播放系統 影吧系統的架構圖 架構體系 解決方案 1. 運行平臺:跨平臺 android ios pc mobile 1.1. 前端 界面 1.2. Web組件化 Js css html的動態載入 ,容器化運行,ajax iframe 1.3. Css icon類庫 1.4. ...
  • 裝飾模式(Decorator) 定義 裝飾模式(Decorator),動態地給一個對象添加一些額外的職責,就增加功能來說,裝飾模式比生成子類更為靈活。 類圖 描述 Component:被裝飾者和裝飾者共有的基類; ConcreteComponent:被裝飾者的具體類; Decorator:裝飾類,包 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...