微信紅包的設計實現


紅包功能的設計實現是一個很有趣的話題,主要的功能是P個人搶總金額M的N個紅包,滿足先搶的N個人能搶到紅包。如果這是一個leetcode的算法題目難度應該是easy,只要保證Ni搶到的金額區間在[0.01,2倍剩余金額平均值)就能ac。
將算法帶入到真實的工程實現,問題就要復雜得多,如果達到微信的量級,明顯要考慮的有以下幾點。

  1. 拆紅包
  2. 高並發讀
  3. 並發寫
  4. 網絡流量峰值
  5. 對賬
  6. 降級
  7. 故障恢復

拆紅包

拆紅包有預拆包和實時拆包2種策略

預拆包策略

預拆包的策略在發紅包時將金額M的紅包拆分成N份,將分配好的結果放入內存隊列或者cache,通過incr操作在用戶搶紅包時分配預算好的紅包slot,預算的策略可以避免對共享資源的操作,減少了鎖競爭,服務本身是無狀態的,設計和實現相對簡單,伸縮性較好。劣勢是需要額外的存儲空間,如果存在大量活躍紅包或者紅包份數很多時會增加成本。

實時拆包

實時拆包的策略在用戶搶紅包時實時拆包計算金額,這樣只需要保存剩余紅包數量和金額,不需要額外保存每個預拆包的紅包金額。使用預拆包的策略會面臨並發寫的問題,如果多個拆紅包的請求同時執行會導致數據不一致引起超發的問題,可以使用CAS操作實現樂觀鎖保證並發拆包不會出現問題。

高並發讀

應對高並發讀的通常思路是業務層攔截過濾無效請求,使用有效的緩存。可以使用Cache層decr功能記錄請求紅包的用戶數,當decr到0后就攔截后面的請求直接返回,對DAO層也要增加相應的緩存減少數據庫的壓力。

並發寫

應對並發寫的通常思路是串行化和樂觀鎖。在用戶搶紅包時實時拆包計算金額,每搶到一個紅包,就cas更新剩余金額和紅包個數,同時在DB中記錄憑證,考慮到DB的寫入壓力,需要做分庫分表,冷熱分離。

網絡流量峰值

大量用戶同時搶紅包是否會造成網絡擁塞,發紅包和搶紅包最好在同一個IDC。

對賬

考慮到拆紅包憑證和入賬是異步的2套系統,以及出現故障的可能,需要定時對賬保證數據的一致性。

降級

在cache故障時有限流的使用DB進行服務,在資源緊張的時候關閉掉非核心流程,在實時入賬請求量過大時,延遲批量入賬。


Reference:
https://www.zybuluo.com/yulin718/note/93148


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM