一、问题
近期有个项目,客户要求加个抢红包功能,需求提的是要满足20亿以上流量,那么总共有20亿个红包,在某个时间一起来抢红包,如何设计?
二、分析思路
根据对目前业务的了解,系统不可能达到这种级别的流量,但客户考虑的是权限情况,实际解决这个问题,主要考察的是如何设计Java高并发系统。
![6838caa1af7c9f99b1a5b2aaa9900358.png](https://i-blog.csdnimg.cn/blog_migrate/8e2f76c3ea1003d5eb8a4e4cadb11711.jpeg)
我分析,解决这个问题不能只从技术上考虑,可以采用一些变通的处理方式。
通常在考虑系统QPS(每秒的查询量)时,应当按业务上的极限QPS作为系统必须承担的QPS设计,比如20亿个红包,因为用户量巨大,极限QPS是可能是20亿,甚至更高。
但一般来说几万QPS已经是比较高的并发了,如今这么高的并发就要采用比较大的集群和高并发架构来处理了,根据项目预算,不可能真正实现20亿的并发架构,只能通过一些变通的方法来处理,比如在业务上做一些处理,规避掉部分不合理流量。
当然首先要从技术上实现高并发架构,思路是将请求流量尽量拦截在系统上游(不要让锁冲突落到数据库上去),至于怎么将请求拦截在系统上游,后面文章中会详细说明,今天只是分析思路。
![697dff89ffd1991f5c5164030f89442f.png](https://i-blog.csdnimg.cn/blog_migrate/6ceff7a79a656a7c6bd137f7952d16f8.jpeg)
三、解决办法
业务上适当规避
制定相应规章制度、活动说明,在考虑用户体验情况下,可以做以下处理:
- 根据某些规则对部分用户直接返回没抢到。比如有些用户曾经被系统识别为恶意用户、垃圾用户、僵尸用户,直接告诉用户已经抢完;
- 分散不同客户端打开活动入口的时间。比如将1秒内的20亿流量分散到20秒,那么平均每秒只有1亿了;
- 增加客户端入口点击门槛。比如需要手机摇一摇、画一个图案才能触发抢红包的接口、抢一次后,要10秒才能再次提交。
![d7be41a77848c595cbfa5cdf471f14f9.png](https://i-blog.csdnimg.cn/blog_migrate/54c8d789523dffd878a23f58822ab756.jpeg)
技术上提高抗压能力
网络上是会接触到20亿流量的地方,可以利用网络手段拦截掉无效流量,另一种是采用缓存技术
- 限流策略。比如在压力测试中我们测到系统1亿QPS达到了极限,那么超过的部分直接返回已经抢完,通过Nginx的lua脚本可以查redis看到QPS数据从而可以动态调节;
- 作弊拦截。通过对UA、IP规则直接将抢红包的作弊流量拦截掉;
- 异步削峰。对Redis中的红包预减数量,立即返回抢红包成功请用户等待,然后把发送消息发给消息队列,进行流量的第二次削峰,让后台服务慢慢处理;
- 服务逻辑。比如业务逻辑是使用事务控制对数据库的创建红包记录,减红包数量的操作,那么创建操作要放到减数量操作之前,从而避免减数量update的行锁持有时间;
- 机器配置。当然是服务器机器配置越高越好,数据库配置越猛越好,高并发抢红包主要是CPU的负载较高,要选择偏向CPU性能的机器;
以上,是我结合相关资料和自己的经验谈了一些思路,解决方法仅供参考,有什么好的解决方法或思路,可以评论区交流。
我是一名码龄10年的程序员,在这里会分享实在干货,让你少走弯路,成就精彩人生。