php laravel 抢红包防止并发(超卖也是同理)

4 篇文章 0 订阅

方案1:

          原理:后台创建红包后,将红包个数存入redis,采用常量键名拼接红包id 作为key,红包个数为value存入redis,然后当用户领取红包的时候,前端肯定传红包id到后端,后端 先加redis锁,然后根据接收的红包id 读取key对应的值就是红包剩余个数,然后减1后再存入。

具体代码如下(php--laravel)

 

方案2:(不加锁利用redis原子性,还是建议使用方案一)

首先要了解的是:1.Redis如何保证原子性?

                              答案很简单,因为redis是单线程。

一、看下面代码(仅仅是看,后面贴的有代码可复制)

 

分析:通过jmeter并发测试发现仍然出现类似超卖情况,

          上图中 llen 和 lpush 两次操作如果单独执行是具备原子性的,但是这两个操作组合起来才算是完成一个业务,那么这2个命令组合起来就不具备原子性,所有在两个操作之间其他客户端会出现脏读。

 

二、再优化代码如下:

在后台设置红包的时候执行以下操作,

然后用户领取红包请求接口的时候只做一步redis操作。

public function getPacket(Request $request) {
        
        $packet_id = $request->input('packet_id',0);
        if(!$packet_id){
            return Response::error('缺少参数:packet_id') ;

        }
        $redisConfig = config('database.redis.default');
        $redis = new Client($redisConfig);
        $count = $redis->lpop('red_packet_id:'.$packet_id);
        if(!$count){
            return Response::error('已经抢光了哦') ;
        }
        return Response::success('恭喜您,抢到了哦!') ;

    }

总结:

        这里利用 redis 操作的原子性来实现。首先我们把 红包个数或者库存 存在“red_packet_id:1”这个列表中,假设id=1的这个红包的可领取个数为10个,就往列表中push10个数,这个数没有实际意义,仅仅只是代表红包的可被领取次数。抢购或者红包到开始领取时间后,每到来一个用户,就从“red_packet_id:1”中 pop 一个数,表示用户抢购成功。当列表为空时,表示已经被抢光了。因为列表的pop操作是原子的,即使有很多用户同时到达,也是依次执行的。

       缺陷:1、单纯依靠这总办法解决并发是不够的。

                  2、这种办法如果红包个数1000个是要往队列插入1000条,方案有点low,

                  3、队列一般都是用来异步处理,上面方案是同步消费队列返回给前端,所以这种方案不是很完美,但是能够实现。

  

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在JMeter中进行抢红包并发测试,可以按照以下步骤进行设置: 1. 新建一个测试计划,在测试计划中右击,选择"添加" -> "Threads (Users)" -> "线程组",创建一个名为"抢红包测试"的线程组。 2. 在线程组下添加一个HTTP请求,右击线程组,选择"添加" -> "Sampler" -> "HTTP请求",并将其命名为"抢红包"。 3. 在HTTP请求中设置相关的请求参数,包括URL、请求方法、请求头、请求参数等,以模拟抢红包的操作。 4. 在线程组的属性中设置并发数,即同时并发执行抢红包的线程数量。可以在线程组的属性中设置"线程数"和"循环次数"来控制并发测试的规模。 5. 运行测试计划,JMeter会模拟多个用户同时进行抢红包的操作,并记录相应的响应时间和吞吐量等性能指标。 需要注意的是,为了准确模拟真实的并发场景,还可以在测试计划中添加其他相关的元素,如定时器、监听器等,来更好地控制并发场景下的压力测试。 总结:要在JMeter中进行抢红包并发测试,首先要创建一个名为"抢红包测试"的线程组,然后在线程组中添加一个名为"抢红包"的HTTP请求,并设置相关的请求参数。最后设置并发数,运行测试计划即可进行抢红包并发测试。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [JMeter压力测试(流程骨架/抢红包举例实战/多场景多线程组混合并发)](https://blog.csdn.net/xqtesting/article/details/85090026)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值