在我们的生活中,发红包和抢红包已经成了过年过节的娱乐项目,可以说是非常的火爆,上到爸妈,(爷爷奶奶就不提了)下到7-8岁孩子,都会使用,当然90%的使用的都是微信红包或者QQ红包,但是身为程序员的我们知道红包派发和抢是怎么实现的吗?
接下来就一起梳理一下微信发红包的业务流程:
首先可能会拉一个群组,或者在家庭群中,选择发红包的功能,然后弹出发红包的页面,输入要派发的金额,然后点击塞进红包,接着会弹出一个选择支付方式的窗口,然后选择后,输入密码,点确认,红包就派发成功了。然后根据红包限定的个数和金额由群里的家人朋友开始抢,抢完为止。这个是派发红包的操作流程,然后思考一下,派发红包看似简单的几步操作,但是由于操作的人过多,就会造成高并发,想下,过节的时候,随随便便就是百万级并发,然而面对高并发,微信后台派发红包他究竟做了什么呢?
派发红包的时候后台操作流程:
发红包:系统为每个红包分配一个唯一 ID,即红包发送订单号,然后将发红包用户、红包个数、红包数额写入存储,最后去微信支付下单。用户使用微信支付完成付款,微信红包后台系统收到微信支付系统的支付成功通知。红包系统将红包发送订单状态更新为用户已支付,并写入用户发红包记录(用户发红包记录,就是微信钱包中,查看到的用户每一年总共发出及收到的红包记录)。最后微信红包后台系统发送微信红包消息到微信群。
抢红包:指微信群里的用户收到微信红包消息后,点开红包消息。这个过程,微信红包后台系统会检查红包是否已被抢完,是否已过期,是否已经抢过。
拆红包 :是最复杂的业务是操作。包括查询这个红包发送订单,判断用户是否可拆,不能出现用户反复拆当前红包,然后计算本次可拆到的红包金额,不能出现用户拆的红包的金额合计超过或者小于红包总金额另外,不能出现手快的没拆到红包,手慢的拆到红包了。然后写入一条抢红包记录。如果把拆红包过程,类比为一个秒杀活动的过程,相当于扣库存与写入秒杀记录的过程。更新库存对应于更新红包发送订单,写入秒杀记录对应于写入这个红包的领取红包记录。另外,还要写入用户整体的红包领取记录。最后请求微信支付系统给拆到红包用户转入零钱,成功后更新抢红包的订单状态为已转账成功。
对于系统可用性影响因素
系统的可用性影响因素可分成两类,一类计划外,一类计划内。计划外包含很多因素,系统用到的所有东西都可能产生故障,都可能成功影响可用性的因素。从这个角度上来讲,可以说故障是无法避免的,系统的运作一定会产生故障,尤其是服务器有成千上万个的时候。计划内的影响因素,主要有与升级相关、运维相关的操作,以及日常的备份等。这一类影响因素,通过精细地设计方案,是可以避免对可用性造成影响的。
微信红包系统可用性设计方向
基于上面两个分析结论,可以总结出微信红包后台系统的可用性的设计方向。就是在不能避免意外故障的情况下,尽可能降低出现意外故障时对可用性的影响。另一方面,绝大多数计划内的日常维护可以通过方案的设计避免影响可用性,其中平行扩容特指关于存储层的平行扩容。
主要运用缓存和异步来优化功能,提高性能,减少DB的操作,然后针对DB也可以进行优化
存储层的高可用设计
读写分离
写请求需要在DB主机上,实时读也需要走主机。有大量对延时不那么敏感,又影响性能的查询,完全可以放到DB从机。读写分离策略是MySQL分布式的入门,简洁地提高了系统容量。
水平切分
数据的水平切分,实质就是分库分表;选取一张数据表按照主要纬度把数据拆分开。实现存储层的平行扩展。有效降低了单台数据库机器的负载,也减小了服务不可用的可能性。单台数据库宕机只会导致部分数据不能访问。主要需要考虑路由规则的选定,方便扩缩容以及数据的均衡分布。
垂直切分
数据表除了水平切分,行内数据可以按属性进一步分开。核心表只保留最关键的字段,保证数据文件短小紧凑。以红包为例,昵称和祝福语这类较长的信息,不属于核心数据,完全可以切分到别的机器上,进一步提升核心数据库的容量。不同数据适合的存储类型也不一样,这类重复率高的长字符串更适合NoSQL存储,对存储空间和性能都是节约极大。
空间换时间
按不同纬度组织表,比如按订单属性和用户属性进行组织;适应不同的请求场景,避免复杂的查询。不同纬度的表可以通过对账对齐,非核心表可以适当冗余,减少多次请求。
锁的优化
多人争抢红包通过数据库事物来保证,必然存在竞争MySQL行锁。核心事物必须尽量精简,避免死锁。同一个订单的所有请求,尽量在逻辑层进程预排队后通过一个连接发送请求到数据库。
冷热分离
核心数据库存放高频数据,其他数据可以定时移到成本低的冷数据库中。