• 企业400电话
  • 微网小程序
  • AI电话机器人
  • 电商代运营
  • 全 部 栏 目

    企业400电话 网络优化推广 AI电话机器人 呼叫中心 网站建设 商标✡知产 微网小程序 电商运营 彩铃•短信 增值拓展业务
    PHP+redis实现的限制抢购防止商品超发功能详解

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

    文件index.php

    ?php
    require_once './myRedis.php';
    require_once './function.php';
    class sendAward{
      public $conf = [];
      const V1 = 'way1';//版本一
      const V2 = 'way2';//版本二
      const AMOUNTLIMIT = 5;//抢购数量限制
      const INCRAMOUNT = 1;//redis递增数量值
      //初始化调用对应方法执行商品发放
      public function __construct($conf,$type){
        $this->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

    ?php
    /**
     * @desc 自定义redis操作类
     * **/
    class myRedis{
      public $handler = NULL;
      public function __construct($conf){
        $this->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

    ?php
    //获取商品key名称
    function getKeyName($v)
    {
      return "send_goods_".$v;
    }
    //日志写入方法
    function writeLog($msg,$v)
    {
      $log = $msg.PHP_EOL;
      file_put_contents("log/$v.log",$log,FILE_APPEND);
    }
    
    

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

    [root@localhost oversend]# ab -c 100 -n 200 http://192.168.0.213:8083/index.php?v=way1
    This 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 requests
    Completed 200 requests
    Finished 200 requests
    Server Software:    nginx
    Server Hostname:    192.168.0.213
    Server Port:      8083
    Document Path:     /index.php?v=way1
    Document Length:    0 bytes
    Concurrency Level:   100
    Time taken for tests:  0.089 seconds
    Complete requests:   200
    Failed requests:    0
    Write errors:      0
    Total transferred:   30600 bytes
    HTML transferred:    0 bytes
    Requests 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] received
    Connection Times (ms)
           min mean[+/-sd] median  max
    Connect:    0  6  2.2   5   17
    Processing:   2  28 16.3   25   55
    Waiting:    1  26 15.2   24   50
    Total:     5  34 16.3   30   60
    Percentage 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=way2
    This 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 requests
    Completed 200 requests
    Finished 200 requests
    Server Software:    nginx
    Server Hostname:    192.168.0.213
    Server Port:      8083
    Document Path:     /index.php?v=way2
    Document Length:    0 bytes
    Concurrency Level:   100
    Time taken for tests:  0.087 seconds
    Complete requests:   200
    Failed requests:    0
    Write errors:      0
    Total transferred:   31059 bytes
    HTML transferred:    0 bytes
    Requests 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] received
    Connection Times (ms)
           min mean[+/-sd] median  max
    Connect:    0  6  5.4   5   13
    Processing:   3  31 16.6   30   70
    Waiting:    1  30 16.6   30   70
    Total:     5  37 18.5   32   82
    Percentage 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扩展无法加载的问题解决方法
    • thinkPHP框架通过Redis实现增删改查操作的方法详解
    • PHP商品秒杀问题解决方案实例详解【mysql与redis】
    • PHP+Redis链表解决高并发下商品超卖问题(实现原理及步骤)
    上一篇:php+redis实现消息队列功能示例
    下一篇:php使用yield对性能提升的测试实例分析
  • 相关文章
  • 

    © 2016-2020 巨人网络通讯 版权所有

    《增值电信业务经营许可证》 苏ICP备15040257号-8

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