php与redis 实现秒杀过程

7 篇文章 0 订阅

参考网址
https://blog.csdn.net/Srodong/article/details/88656214
https://blog.csdn.net/feiwutudou/article/details/80337141
https://blog.csdn.net/qq_36573434/article/details/98764640
https://blog.csdn.net/weixin_44699468/article/details/89362099

步骤

1 开启redis服务   到redis目录,shift + 右键,打开命令行 	.\redis-cli.exe -h 127.0.0.1 -p 6379       
													.\redis-server.exe redis.windows.conf
2 安装redis扩展
3 连接

E:\phpstudy2018\PHPTutorial\Apache\bin>ab -n 800 -c 800  http://www.hlayui.com/admin/reedis  执行

第1种 参照 https://blog.csdn.net/Srodong/article/details/88656214

<?php
namespace app\admin\controller;
use think\Controller;
use app\index\controller\Commen;  
use think\Session;
use think\Db;
use think\Request;
use think\cache\driver\Redis;

// store商品表  order订单表  log日志表
// 把库存数量放入了good_number里,这个redis的名字,然后pop的时候,判断这个redis的长度来判断是否秒杀结束

class Reedis extends Controller 
{

    public function index()
    {
    	$wheres = array();
    	$wheres['goods_id'] = 1;
   
    	$number = DB::name('store')->where($wheres)->value('number');

    	// echo $number;

        $redis = new \Redis();

		$redis->connect('127.0.0.1', 6379);

		for($i=0;$i<$number;$i++){  
		    $redis->lpush('goods_number',1);  
		}  
		echo $redis->llen('goods_number');  
    }
 

    
	  
	//模拟下单操作  
	//下单前判断redis队列库存量  
	function order(){
        $sku_id  = 11;  //传入已知的sku_id;
    
        $wheres = array();
    	$wheres['sku_id'] = $sku_id;
    	$good_info = DB::name('store')->where($wheres)->find();
 
		$user_id  = rand(1,200);
		$goods_id = $good_info['goods_id'];
		$price    = $good_info['price'];
		$number   = 1;		//抢购时每次买一件商品
 
		$redis = new \Redis();
		$redis->connect('127.0.0.1', 6379);

		$count=$redis->rpop('goods_number');  //下单时做rpop 从goods_number中取出1
		if($count == 0){  
		    $this->insertLog('error:no goods_number redis');  
		    return;  
		}
 
 
        if( ($good_info['number'] - $number) <= 0){
            $this->insertLog('商品售罄');  //如果库存为0写入日志 并停止下单操作
            return;
        }
		 
		
		//生成订单    
		$order_sn=$this->build_order_no();
 
        $data = array();
        $data['order_sn'] = $order_sn;
        $data['user_id']  = $user_id;
        $data['goods_id'] = $goods_id;
        $data['sku_id']   = $sku_id;
        $data['number']   = $number;
        $data['price']    = $price;
 
		$order_rs = DB::name('order')->insert($data);
		  
		//库存减少  
		$wheres['sku_id'] = $sku_id;
		$store_rs = DB::name('store')->where($wheres)->setDec('number',$number);
		if($store_rs){
		    $this->insertLog('库存减少成功');  
		}else{    
		    $this->insertLog('库存减少失败');  
		}
	}


	//生成唯一订单号  
	function build_order_no(){  
	    return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8);  
	}  


	//记录日志  
	function insertLog($event,$type=0)
	{
        $data['event'] = $event;
        $data['type']  = $type;
	    $res = DB::name('log')->insert($data);
	}  

}

初始store 表
在这里插入图片描述
程序执行,调用的 order 方法
在这里插入图片描述执行完毕后
在这里插入图片描述在这里插入图片描述在这里插入图片描述

第2种 https://blog.csdn.net/weixin_44699468/article/details/89362099

<?php
namespace app\admin\controller;
use think\Controller;
use app\index\controller\Commen;  
use think\Session;
use think\Db;
use think\Request;
use think\cache\driver\Redis;

class Reedis extends Controller 
{

    public function index(){
        //首先,加载一个Reids组件,
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);

        $mywatchkey = $redis->get("mywatchkey"); 
		$rob_total = 100;   //抢购数量
		if($mywatchkey<$rob_total){ 
			$redis->watch("mywatchkey"); 
			$redis->multi(); 
			 //设置延迟,方便测试效果。 
			 sleep(5); 
			  //插入抢购数据
			  $redis->hSet("mywatchlist","user_id_".mt_rand(1, 9999),time());
			  $redis->set("mywatchkey",$mywatchkey+1); 
			  $rob_result = $redis->exec(); 
			   if($rob_result){ 
			   		$mywatchlist = $redis->hGetAll("mywatchlist");
			   		echo "抢购成功!<br/>";
			   		echo "剩余数量:".($rob_total-$mywatchkey-1)."<br/>"; 
			   		echo "用户列表:<pre>"; 
			   		var_dump($mywatchlist); 
			  }else{
			  	echo "手气不好,再抢购!";exit;  
			  }
		}
    }
}

第3种 https://blog.csdn.net/qq_36573434/article/details/98764640

<?php
namespace app\admin\controller;

use think\Controller;
use app\index\controller\Commen;  
use think\Session;
use think\Db;
use think\Request;
use think\cache\driver\Redis;

class Reedis extends Controller 
{
    public function index(){
        //首先,加载一个Reids组件,
        $redis = new \Redis();
        $redis->connect('127.0.0.1', 6379);
        $admin = Session('admin');
        $redis_name = 'miaosha';
        $uid = $admin['username'];
        //设置参加数量
        $num = 40;
        
        // 如果当前人数少于20的时候,则加入这个队列
        // 通过 redis_name 长度来判断是否秒杀结束
        
        if ($redis->lLen($redis_name)<= $num) {
            //执行数据库操作
            $res = true;//'增删改查';
            //如果为真,则往队列新增
            if($res){
                $redis->LPush($redis_name,$uid);
            }else{
            	var_dump('很不幸,未能参加抢购成功');
                // $this->error('很不幸,未能参加抢购成功');
            }
            $user_list = $redis->Lrange($redis_name,0,20);
            var_dump($user_list);//可以查看list的内容
        }else{
            //如果当前人数已经达到20人,责任返回秒杀已完成
            echo '秒杀已结束';
        }
        $redis->close();
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值