经常有人问我,大量用户在同一时间点抢红包,服务器是不是压力很大,这个到底怎么处理比较好,今天就写一下大概我的一些经验和一些思路供大家参考。
hihiabc原创,转载请注明出处。
红包的整个过程分为发红包阶段和抢红包阶段,发红包分两种,一种是随机红包,一种是等额红包,而抢红包也分为两种情况,一种是红包还有,说明抢到了,一种是已经没有了。
下面具体计解:
一,发红包阶段,输入数据,首先是用户在界面操作发红包功能,支付成功,上传数据,到后台,后台验证通过。这一步没有太多问题。主要是验证好数据合法性,不要出现安全问题。
二,发红包阶段,后台开始计算每个红包金额。
对于等额的红包,当然没有太多问题,不需要计算,对于随机的红包,就需要根据总金额和红包个数来计算每人红包到底是多少。这个具体的算法后面再讲,大概就是根据个数和总金额为依据,有多种实现方式,网上也有很多红包算法实现,大概是两个思路, 一是设置最低红包和最高红包然后找一些随时数来算出每个红包,二是先平分,再随时调整每一个红包的大小,这里就先不细讲。这个要用代码才说得清楚。
三,发红包阶段,保存红包。
红包计算好以后,需要有地方保存,当然首先是数据库应该有一份完整的数据,其次是往消息队列服务器发送一份数据。或者往缓存发送一份数据也行。总之这个数据在用户开始抢的时候就需要用到了。
四,通知客户端有人发红包了。
这个过程没有太多的说的,主要是每个平台里面自己实现,有些平台用长链接,有些平台用短链接,该通知哪些人,或者哪个群,平台自己实现就行。不过这种数据最好加密或者使用https传输。
五,用户开始抢红包,高潮的部分来了。
假如现在有100个红包,但是有10万个人点进来了怎么办,服务器是不是要挂掉了。这个地方有一些巧秒的算法大概说一说。
首先,每个红包的金额我们已经算好了,所以这个地方已经省去了很多麻烦,不用每个请求进来都去计算一次。
第二,我们根据红包的个数我们设计一个队列,比如这里设计一个100长度的就够了,实际做的时候可以稍微长一点,用户抢红包的请求进来以后,我们让这100个人排队处理分红包,这个过程也很快,直接去红包数据里面一个个取就是了,然后在缓存里面用一个变量记录一下当前红包已经没有了,这100个人以后的请求直接通过这个变量就直接返回没有了,这100个人以后的请求只需要一个变量的判断,所以处理速度是相当快,有再多的请求进来也不怕。只要你的缓存生效,不至于去查数据库就没问题,这个地方也要仔细设计,不能出现缓存穿透的情况。
记得并发的时候边界的处理,这个在具体实现的考虑就可以了。这理就不仔细讲了。
六, 有些情况下可以减少请求,就是让客户端知道这个红包已经没有了,这种情况,也许都不需要发请求到后台,直接提示红包已经没有了,这种做法看上去虽不好,但也确实有人使用过,而且这种请求也是无效请求。比如在自己平台里面规定,红包超过24小时就不能抢了,这种抢红包的请求就不需要发后台了。在界面上直接提示就可以了。不过后台也要能处理,万一在界面上没有生理好,或者万一有人绕过界面处理,所以后台比较要处理,这种情况,后台根据时间判断后直接返回就可以了。没有任何问题。
秒杀也一样,只是秒杀不用预先计算数据,秒杀是减库存。思路都有类似的地方。