Redis 队列实现并发抢红包逻辑?
使用laravel5.5+mysql5.7+redis.3.x
最近处理抢红包逻辑,遇到一些问题。
页面逻辑
- 用户发出红包(初始化红包)
- 用户分享
- 其他用户点击进入(可以理解为红包详情页)
- 点击“抢”按钮,发出抢红包请求
- 根据请求结果显示用户是否抢到红包
一、方案一
1. 流程图
2. 介绍
这个方案主要是提前计算出每个小红包的金额插入到队列,然后领取时进行出队操作。
3. 疑问
- 提前插入队列,在红包数量
total_size>1000
的情况下会比较慢 - 在进行出队操作时如何与前端页面交互?
在抢红包时发送请求到服务器端,服务器端应该返回给我是否成功操作,但是由于在Lavael中出队操作是异步(。。。也就是说这个请求并不能返回我到底有没有抢到红包),我该如何判断状态?难道要比如过5s后再执行ajax请求看一下数据库里队列任务是否生成了领取记录?二 、方案二
1. 流程图
2. 介绍
这个方案是在“抢”红包的时候生成随机金额,然后插入到队列,之后取前几名
3. 疑问
- 这个操作只有在高并发(并发数>total_size)时使用
- 同方案一,如何处理队列的异步处理问题。
主要问题:如何处理队列的异步处理问题。看了其他一些解决方案,大致都是说用队列处理并发问题,但是在抢红包请求中,队列操作是异步的,也就是说,我这个抢的请求是获取不到正确结果的(只有队列执行完成),难道要比如过5s后再执行ajax请求看一下数据库里队列任务是否生成了领取记录?。。。
队列之前没有用过。。。所以希望大神们给点意见。或者更好的解决方案
基于redis的抢红包方案。
把原始的红包称为大红包,拆分后的红包称为小红包。
1.小红包预先生成,插到数据库里,红包对应的用户ID是null。
2.每个大红包对应两个redis队列,一个是未消费红包队列,另一个是已消费红包队列。开始时,把未抢的小红包全放到未消费红包队列里。
未消费红包队列里是json字符串,如{userId:'789', money:'300'}。
3.在redis中用一个map来过滤已抢到红包的用户。
4.抢红包时,先判断用户是否抢过红包,如果没有,则从未消费红包队列中取出一个小红包,再push到另一个已消费队列中,最后把用户ID放入去重的map中。
5.用一个单线程批量把已消费队列里的红包取出来,再批量update红包的用户ID到数据库里。
这个是方案一的详细过程,但是还是那个问题,队列是异步执行,导致抢红包的请求并没有马上得到结果。而是要等队列执行完毕才可以判断用户是否抢到红包。
抢红包最终实现效果~,有需要源码的私聊我~
推荐文章: