答:微信从财付通拉取金额数据过来,生成个数/红包类型/金额放到redis集群里,app端将红包ID的请求放入请求队列中,如果发现超过红包的个数,直接返回。根据红包的逻辑处理成功得到令牌请求,则由财付通进行一致性调用,通过像比特币一样,两边保存交易记录,交易后交给第三方服务审计,如果交易过程中出现不一致就强制回归。
【5】问:并发性处理:红包如何计算被抢完?
答:cache会抵抗无效请求,将无效的请求过滤掉,实际进入到后台的量不大。cache记录红包个数,原子操作进行个数递减,到 0 表示被抢光。财付通按照 20万笔每秒入账准备,但实际还不到 8万每秒。
【6】问:通如何保持8w每秒的写入?
答:多主sharding,水平扩展机器。
【7】问:数据容量多少?
答:一个红包只占一条记录,有效期只有几天,因此不需要太多空间。
【8】问:查询红包分配,压力大不?
答:抢到红包的人数和红包都在一条cache记录上,没有太大的查询压力。
【9】问:一个红包一个队列?
答:没有队列,一个红包一条数据,数据上有一个计数器字段。
【10】问:有没有从数据上证明每个红包的概率是不是均等?
答:不是绝对均等,就是一个简单的拍脑袋算法。
【11】问:拍脑袋算法,会不会出现两个最佳?
答:会出现金额一样的,但是手气最佳只有一个,先抢到的那个最佳。
【12】问:每领一个红包就更新数据么?
答:每抢到一个红包,就cas更新剩余金额和红包个数。
【13】问:红包如何入库入账?
答:数据库会累加已经领取的个数与金额,插入一条领取记录。入账则是后台异步操作。
【14】问:入帐出错怎么办?比如红包个数没了,但余额还有?
答:最后会有一个take all操作。另外还有一个对账来保障。
【15】问:既然在抢的时候有原子减了就不应该出现抢到了拆开没有的情况?
答:这里的原子减并不是真正意义上的原子操作,是Cache层提供的CAS,通过比较版本号不断尝试。
【16】问:cache和db挂了怎么办?
答:主备 对账。
【17】问:为什么要分离抢和拆?
答:总思路是设置多层过滤网,层层筛选,层层减少流量和压力。
这个设计最初是因为抢操作是业务层,拆是入账操作,一个操作太重了,而且中断率高。 从接口层面看,第一个接口纯缓存操作,搞压能力强,一个简单查询Cache挡住了绝大部分用户,做了第一道筛选,所以大部分人会看到已经抢完了的提示。
【18】问:抢到红包后再发红包或者提现,这里有什么策略吗?
答:大额优先入账策略。
针对上面的技术要点,有人还画了张原理图(这是网上能找到的相对清晰的版本):
3.2、微信抢红包的过程模拟针对上节中整理的资料,当有人在微信群里发了一个 N 人的红包、总金额 M 元,后台大概的技术逻辑如下。
3.2.1)发红包后台操作:
1)在数据库中增加一条红包记录,存储到CKV,设置过期时间;