当有人在微信群里发了一个 N 人的红包、总金额 M 元,后台大概的技术逻辑如下。
发红包后台操作:
1)在数据库中增加一条红包记录,存储到CKV,设置过期时间;
2)在Cache(可能是腾讯内部kv数据库,基于内存,有落地,有内核态网络处理模块,以内核模块形式提供服务))中增加一条记录,存储抢红包的人数N。
抢红包后台操作:
1)抢红包分为抢和拆:抢操作在Cache层完成,通过原子减操作进行红包数递减,到0就说明抢光了,最终实际进入后台拆操作的量不大,通过操作的分离将无效请求直接挡在Cache层外面。这里的原子减操作并不是真正意义上的原子减操作,是其Cache层提供的CAS,通过比较版本号不断尝试,存在一定程度上的冲突,冲突的用户会放行,让其进入下一步拆的操作,这也解释了为啥有用户抢到了拆开发现领完了的情况。
2)拆红包在数据库完成:通过数据库的事务操作累加已经领取的个数和金额,插入一条领取流水,入账为异步操作,这也解释了为啥在春节期间红包领取后在余额中看不到。拆的时候会实时计算金额,其金额为1分到剩余平均值2倍之间随机数,一个总金额为M元的红包,最大的红包为 M * 2 /N(且不会超过M),当拆了红包后会更新剩余金额和个数。财付通按20万笔每秒入账准备,实际只到8万每秒。
比如100元,由10个人分,那么平均一个人是10元钱。然后付款后,系统开始分份儿。
第一份:系统由0~10元之间随机一个数,作为这一份的钱数,设x1。
第二份:剩下的钱(100-x1),系统由0~(100-x1)/(10-1)随机一个数,作为这份的钱数,设x2
.。。。
第n份:剩下的钱(100-x1-x2-...-xn),系统由0~(100-x1-x2-...-xn-1)/(10-n)随机一个数,作为这个份的钱数,设为xn
当用户进来拿红包的时候,系统由0~9之间随机一个数,随机到几,就取第几份红包,然后将这个数存到list里。当之后的用户抽到相同的随机数时,则将这个数+1,如遇相同再+1,直至list满,红包发完。
发红包:红包发送者在微信中设置红包金额和数量,并点击发送。
生成随机数池:系统会生成一个随机数池,这个池子中的金额是不断变化的。根据红包金额和数量,系统会计算出一个随机数池的范围。
预分配红包金额:系统会预先将红包金额分配给每个红包,但是还没有实际给到领取者手中。
领取红包:领取红包的人点击打开红包后,系统会根据随机算法从随机数池中抽取一个随机数。
计算红包金额:系统根据抽取的随机数和预分配的金额,计算出这个红包的实际金额。
返回领取者:系统将计算出的实际金额返回给领取者,红包领取完成。
微信红包的随机算法主要依赖于生成随机数池和抽取随机数的过程,通过合理的随机算法和数学计算,使得每个红包的金额分布更加随机和公平。
需要注意的是,具体的随机算法和实现细节是微信平台保密的商业机密,这样可以防止恶意攻击者通过破解算法来获取不正当的优势。因此,我们无法获得具体的技术细节。