经典系统设计题:大型抢红包系统设计

本文探讨了微信红包业务流程中的关键环节,如发红包、拆红包过程中的拆分算法(随机数与二倍均值法)、抢红包时的限流与分布式锁使用,以及如何通过消息队列和哈希算法分配金额,同时强调了并发修改和异步处理的重要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

业务流程

以微信红包为例,分为如下流程:

  1. 发红包(包红包);
  2. 抢红包;
  3. 拆红包(开红包)。

发红包

设置金额和份数,完成支付,红包详情入库,为红包生成一个唯一ID。

红包拆分

拆分时机

红包金额拆分分为实时拆分提前拆分,实时拆分对系统性能和拆分算法要求较高,在拆分时既要保证线程安全,又要保证并发效率,开发难度较大。而且拆分过程中要一直保证后续待拆分红包的金额不能为0,不容易做到拆分的红包金额服从正态分布规律。

大型红包系统一般选择提前拆分,从而降低系统复杂度。

拆分算法

随机数

我们假设有一个100元的红包。第一个人可以在0.01元到100元之间,随机地分配到一定金额。如果我们把第一个人抽到的所有可能的金额都计算在内,并取个平均值,那么他平均能获得50元。这50元在数学上还有个形象的名字,叫作数学期望。既然是“期望”,就总会有落空的时候,也不排除会有意外的惊喜。因此,第一个人抽到的金额可能不足50元,也可能大于50元。

第二个人就只能在0.01到剩下的金额之间随机了,显然,第二个人平均能获得的金额比第一个人小,而且越到后面的人,这个平均金额越小。

也就是说,越在前面抢的人越有优势,因此,这个算法非常不公平。

二倍均值法

二倍均值法拆分的金额比较平均,属于“雨露均沾”类型。

假设红包总金额是a,红包个数为p,每个红包的最低金额是0.01元。
那么每次抢到的红包金额的范围在 [0.01, (a / p) * 2] 之间。

算法代码如下:

public class DoubleAVG {
   

    /**
     * 拆分金额
     * @param amount 总金额,单位:元
     * @param part 份数
     * @return
     */
    public static float[] compute(int amount, int part) {
   
        // 红包最低金额0.01元,乘以100以后就可以全部用整型计算,不用担心精度丢失的问题
        int amt = amount 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值