还要提供一个计数器队列总数是10,弹出一个就减去1
视频中采用for循环测试,这个是有序的,所以不会出现超卖现象;如果并发测试的话,会出现超卖现象;这里提供一个解决思路:活动前定义一个长度为10的list;利用lpop的原子性可以保障不会超卖;就是每次请求先lpop,如果可以获取到值,表示秒杀成功;获取不到说明已抢完。
视频中采用for循环测试,这个是有序的,所以不会出现超卖现象;如果并发测试的话,会出现超卖现象;这里提供一个解决思路:活动前定义一个长度为10的list;利用lpop的原子性可以保障不会超卖;就是每次请求先lpop,如果可以获取到值,表示秒杀成功;获取不到说明已抢完。
以课程案例为例,前10个秒杀成功,这个结果是实时的,可以直接返给前端。实际项目时,也是在得到秒杀成功的标识之后,才进行后续的付款操作。
确实会有这样的问题发生,解决方案有两个:
1、提前将秒杀数据写入到队列中,比如你写10个随机数(token)进入队列,然后有请求过来的时候,你开始pop这个token,并判断得到的值是否为空,如果为空说明10个token已经被取完了,秒杀结束。因为pop是redis的原始操作,不用担心重复返回相同值的问题。
2、在你的消费进程中设置为单线程处理,只处理10个记录。
老师的代码是是,插入失败的话,还是放在队列的头部,顺序依旧保持不变,下一次循环还是会继续取出进行插入的。
2个只是测试,如果瞬间有十万个请求(或者更多),存值那块会不会卡住。用redis先存起来(内存操作,速度很快),以后在慢慢存到数据库,
测试是10个 没有问题啊
队列里的数据时异步处理的,然后存进数据库,但是他访问那个连接的时候就相当于多个用户去秒杀了,输出的结果(成功或者结束)就实时的反应了是否秒杀成功。
我也这么想的,肯定是他写错了,口里说的插入左边,写的RPUSH插入右边。。。
redis是单线程,瞬时100个客户端请求过来,还是一条条加入队列,不会一次性进入100个
按照课程的讲法的意思,在pop的时候设置了seelp(2) 两秒钟执行一次pop, 因为秒杀的时候速度非常的快,最多只是微妙数不同,其实在这pop的时间间隔内队列中早已插入了限定的元素个数了不会在插入元素了,也就是说这个时候前端对于秒杀已经判断好了。也就是说已经结束了。这个时候后面在对这十个元素进行入库操作。
因为开始已经在终端执行了一个读取redis缓存的文件,这个PHP文件里面写的是死循环,每2秒读取一次redis的队列。所以后面看到的数据是2秒一次添加进去的。
老师讲得挺清楚的啊,听课时我都是采用1.5X。你提到的那个时间老师再说消息队列的使用场景。
不会,因为有释放redis这个操作,释放redis以后,redis就不会因为队列的长度小于10而进行继续的数据插入了!
这只是参考,要的是思路,你想要完整的实现流程自己去找大神
不应该啊
一般有三种可能
第一种是你的内存太小,可以加内存
第二种是你的某些文件属性不改是只读而设置成了只读,把所有文件属性的只读去掉就行了(可以先整个文件夹所有文件设成只读,再全部去掉只读属性比较快)
再不然就是软硬件有冲突了
把队列名称写成动态或者你复制这几个文件改下队列名称
后端从redis取出入库的时候要保证秒杀任务结束
什么动态变化 是根据未处理状态去取数据,去完就更新了