利用redis List队列简单实现秒杀 PHP代码实现

一 生产者producer部分

 

--------------------------------producer 部分注释------------------------------------------------------------

用户在页面请求之后, 获取到用户uid , 跳转到这个加入队列的方法 (这里直接在producer中模拟了多个uid)

在方法内部判断redis队列长度是否已经达到要求, 如果没有超出, 则执行加入队列的操作 (这里为了简洁,没有封装成方法)

注: producer.php没有进行数据库的操作,只有接受uid和其他值的操作, 数据库操作一律放在消费者consumer.php中

--------------------------------producer 注释结束-----------------------------------------------------------------------

 

生产者代码 producer.php:

<?php//连接redis数据库$redis = new Redis();$redis->connect('127.0.0.1',6379);$redis_name = 'secKill3';//模拟100人请求秒杀(高压力)for ($i = 0; $i < 100; $i++) {    $uid = rand(10000000, 99999999);    //获取当前队列已经拥有的数量,如果人数少于十,则加入这个队列    $num = 10;    if ($redis->lLen($redis_name) < $num) {        $redis->rPush($redis_name, $uid);echo $uid . "秒杀成功"."<br>";} else {//如果当前队列人数已经达到10人,则返回秒杀已完成echo "秒杀已结束<br>";}}//关闭redis连接$redis->close();

 

 

 

注: 执行完producer.php文件,本地redis数据库第0号数据库中应该有一个键名为"secKill3"的List队列,像这样

 

 

二 消费者consumer部分

 

------------------------------消费者部分注释---------------------------------------------

消费者一直读取redis数据库中指定队列,一有值,立即取出,并进行相应数据库操作

------------------------------消费者部分注释结束----------------------------------------

 

消费者代码 consumer.php

 

<?php//设置redis数据库连接及键名$redis = new Redis();$redis->connect('127.0.0.1');$key = 'secKill3';//redis数据库key [注:默认redis数据库选择第0号数据库]//PDO连接mysql数据库$dsn = "mysql:dbname=test;host=127.0.0.1";$pdo = new PDO($dsn, 'root', '123456');//死循环//从队列最前头取出一个值,判断这个值是否存在,取出时间和uid,保存到数据库//数据库插入失败时,要有回滚机制//注: rpush 和lpop是一对while(1) {//从队列最前头取出一个值$uid = $redis->lPop($key);//判断值是否存在if(!$uid || $uid == 'nil'){sleep(2);continue;}//生成订单号$orderNum = build_order_no($uid);//生成订单时间$timeStamp = time();//构造插入数组$user_data = array('uid'=>$uid,'time_stamp'=>$timeStamp,'order_num'=>$orderNum);//将数据保存到数据库$sql = "insert into student (uid,time_stamp,order_num) values (:uid,:time_stamp,:order_num)";$stmt = $pdo->prepare($sql);$res = $stmt->execute($user_data);//数据库插入数据失败,回滚if(!$res){$redis->rPush($key,$uid);}}//生成唯一订单号function build_order_no($uid){return  substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8).$uid;}

 

 

 

注: 执行完consumer.php之后,数据库对应数据表应该有数值

 

到此,秒杀结束

 

备注:

用到的student数据表结构sql

 

CREATE TABLE `student`  (`uid` int(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 'uid',`username` varchar(20) NOT NULL DEFAULT '',`time_stamp` int(11) NOT NULL DEFAULT 0,`order_num` bigint(20) UNSIGNED NOT NULL DEFAULT 0,PRIMARY KEY (`uid`) USING BTREE,key (time_stamp)) ENGINE = MyISAM default charset=utf8;
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值