侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

PHP+redis实现的限制抢购防止商品超发功能详解

Redis  /  管理员 发布于 5年前   276

本文实例讲述了PHP+redis实现的限制抢购防止商品超发功能。分享给大家供大家参考,具体如下:

  • redis不仅仅是单纯的缓存,它还有一些特殊的功能,在一些特殊场景上很好用。redis中key的原子自增incrby和判断key不存在再写入的setnx方法,可以有效的防止超发。
  • 下面使用两个不同的方式来说明利用redis做商品购买库存数量限制。
  • 业务场景很简单,就是限制抢购5个商品,模拟并发请求抢购商品,每抢购一次对应redis中的key值增加一次,通过判断限购的数量来限制抢购,抢购成功写入成功日志,失败写入失败的信息记录,通过记录的数量来判断是否超发。

文件index.php

conf = $conf;    if(empty($type))      return '';    if($type==self::V1){      $this->way1(self::V1);    }elseif($type==self::V2){      $this->way2(self::V2);    }else{      return '';    }  }  //抢购商品方式一  protected function way1($v){    $redis = new myRedis($this->conf);       $keyNmae = getKeyName($v);    if(!$redis->exists($keyNmae)){      $redis->set($keyNmae,0);    }    $currAmount = $redis->get($keyNmae);    if(($currAmount+self::INCRAMOUNT)>self::AMOUNTLIMIT){      writeLog("没有抢到商品",$v);      return;    }    $redis->incrby($keyNmae,self::INCRAMOUNT);    writeLog("抢到商品",$v);  }  //抢购商品方式二  protected function way2($v){    $redis = new myRedis($this->conf);    $keyNmae = getKeyName($v);    if(!$redis->exists($keyNmae)){      $redis->setnx($keyNmae,0);    }    if($redis->incrby($keyNmae,self::INCRAMOUNT) > self::AMOUNTLIMIT){      writeLog("没有抢到商品",$v);      return;    }    writeLog("抢到商品",$v);  }}//实例化调用对应执行方法$type = isset($_GET['v'])?$_GET['v']:'way1';$conf = [  'host'=>'192.168.0.214','port'=>'6379',  'auth'=>'test','db'=>2,];new sendAward($conf,$type);

文件myRedis.php

handler = new Redis();    $this->handler->connect($conf['host'], $conf['port']); //连接Redis    //设置密码    if(isset($conf['auth'])){      $this->handler->auth($conf['auth']); //密码验证    }    //选择数据库    if(isset($conf['db'])){      $this->handler->select($conf['db']);//选择数据库2    }else{      $this->handler->select(0);//默认选择0库    }  }  //获取key的值  public function get($name){    return $this->handler->get($name);  }  //设置key的值  public function set($name,$value){    return $this->handler->set($name,$value);  }  //判断key是否存在  public function exists($key){    if($this->handler->exists($key)){      return true;    }    return false;  }  //当key不存在的设置key的值,存在则不设置  public function setnx($key,$value){    return $this->handler->setnx($key,$value);  }  //将key的数值增加指定数值  public function incrby($key,$value){    return $this->handler->incrBy($key,$value);  }}

文件function.php

1.ab工具并发测试way1方法

[root@localhost oversend]# ab -c 100 -n 200 http://192.168.0.213:8083/index.php?v=way1This is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 192.168.0.213 (be patient)Completed 100 requestsCompleted 200 requestsFinished 200 requestsServer Software:    nginxServer Hostname:    192.168.0.213Server Port:      8083Document Path:     /index.php?v=way1Document Length:    0 bytesConcurrency Level:   100Time taken for tests:  0.089 secondsComplete requests:   200Failed requests:    0Write errors:      0Total transferred:   30600 bytesHTML transferred:    0 bytesRequests per second:  2243.13 [#/sec] (mean)Time per request:    44.581 [ms] (mean)Time per request:    0.446 [ms] (mean, across all concurrent requests)Transfer rate:     335.16 [Kbytes/sec] receivedConnection Times (ms)       min mean[+/-sd] median  maxConnect:    0  6  2.2   5   17Processing:   2  28 16.3   25   55Waiting:    1  26 15.2   24   50Total:     5  34 16.3   30   60Percentage of the requests served within a certain time (ms) 50%   30 66%   35 75%   54 80%   56 90%   57 95%   60 98%   60 99%   60 100%   60 (longest request)

v1方法日志分析

[root@localhost log]# less -N way1.log    1 抢到商品   2 抢到商品   3 抢到商品   4 抢到商品   5 抢到商品   6 抢到商品   7 没有抢到商品   8 没有抢到商品   9 没有抢到商品   10 没有抢到商品   11 没有抢到商品   12 没有抢到商品

观察日志发现 抢到商品的记录有6条超过正常的5条,说明超发了

2.ab工具并发测试way2方法

[root@localhost oversend]# ab -c 100 -n 200 http://192.168.0.213:8083/index.php?v=way2This is ApacheBench, Version 2.3 <$Revision: 655654 $>Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/Licensed to The Apache Software Foundation, http://www.apache.org/Benchmarking 192.168.0.213 (be patient)Completed 100 requestsCompleted 200 requestsFinished 200 requestsServer Software:    nginxServer Hostname:    192.168.0.213Server Port:      8083Document Path:     /index.php?v=way2Document Length:    0 bytesConcurrency Level:   100Time taken for tests:  0.087 secondsComplete requests:   200Failed requests:    0Write errors:      0Total transferred:   31059 bytesHTML transferred:    0 bytesRequests per second:  2311.68 [#/sec] (mean)Time per request:    43.259 [ms] (mean)Time per request:    0.433 [ms] (mean, across all concurrent requests)Transfer rate:     350.58 [Kbytes/sec] receivedConnection Times (ms)       min mean[+/-sd] median  maxConnect:    0  6  5.4   5   13Processing:   3  31 16.6   30   70Waiting:    1  30 16.6   30   70Total:     5  37 18.5   32   82Percentage of the requests served within a certain time (ms) 50%   32 66%   41 75%   45 80%   50 90%   68 95%   80 98%   81 99%   82 100%   82 (longest request)

v2方法日志分析

[root@localhost log]# less -N v2.log [root@localhost log]# less -N way2.log    1 抢到商品   2 抢到商品   3 抢到商品   4 抢到商品   5 没有抢到商品   6 抢到商品   7 没有抢到商品   8 没有抢到商品   9 没有抢到商品   10 没有抢到商品

总结:观察日志可知抢到商品的日志记录是5条并没有超发,说明利用这种方式可以限制住库存的数量。之所以超发是因为方法一中通过加法来判断限制条件的同时,并发一大,就会越过这个判断条件出现会超发,redis的在这方面就体现优势了。

完整代码github地址

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php+redis数据库程序设计技巧总结》、《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

您可能感兴趣的文章:

  • PHP操作Redis数据库常用方法示例
  • PHP的Laravel框架结合MySQL与Redis数据库的使用部署
  • php实现redis数据库指定库号迁移的方法
  • php使用redis的几种常见操作方式和用法示例
  • php使用redis的有序集合zset实现延迟队列应用示例
  • redis+php实现微博(三)微博列表功能详解
  • redis+php实现微博(二)发布与关注功能详解
  • redis+php实现微博(一)注册与登录功能详解
  • PHP商品秒杀问题解决方案实例详解【mysql与redis】
  • php操作redis数据库常见方法实例总结


  • 上一条:
    redis+php实现微博(一)注册与登录功能详解
    下一条:
    php+redis实现消息队列功能示例
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在Redis中能实现的功能、常见应用介绍(0个评论)
    • 2024年Redis面试题之一(0个评论)
    • 在redis缓存常见出错及解决方案(0个评论)
    • 在redis中三种特殊数据类型:地理位置、基数(cardinality)估计、位图(Bitmap)使用场景介绍浅析(2个评论)
    • Redis 删除 key用 del 和 unlink 有啥区别?(1个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2017-12
    • 2020-03
    • 2020-05
    • 2021-04
    • 2022-03
    • 2022-05
    • 2022-08
    • 2023-02
    • 2023-04
    • 2023-07
    • 2024-01
    • 2024-02
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客