一 生产者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;

  

利用redis List队列简单实现秒杀 PHP代码实现的更多相关文章

  1. redis消息队列简单应用

    消息队列出现的原因 随着互联网的高速发展,门户网站.视频直播.电商领域等web应用中,高并发.大数据已经成为基本的标识.淘宝双11.京东618.各种抢购.秒杀活动.以及12306的春运抢票等,他们这些 ...

  2. java-spring基于redis单机版(redisTemplate)实现的分布式锁+redis消息队列,可用于秒杀,定时器,高并发,抢购

    此教程不涉及整合spring整合redis,可另行查阅资料教程. 代码: RedisLock package com.cashloan.analytics.utils; import org.slf4 ...

  3. 后端利用Redis队列及哈希实现定时推送提醒的三个思路

    周煦辰 2016年8月31日 本文介绍了一下本人在开发过程中遇到"定时推送提醒"的需求的时候所思考的三种解决方案. 明确问题 首先明确一下这个需求可能包含的几个"坑&qu ...

  4. 手把手教你用redis实现一个简单的mq消息队列(java)

    众所周知,消息队列是应用系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有 ActiveMQ,RabbitMQ,Zero ...

  5. (转)java redis使用之利用jedis实现redis消息队列

    应用场景 最近在公司做项目,需要对聊天内容进行存储,考虑到数据库查询的IO连接数高.连接频繁的因素,决定利用缓存做. 从网上了解到redis可以对所有的内容进行二进制的存储,而java是可以对所有对象 ...

  6. Java利用Redis实现消息队列

    应用场景 为什么要用redis?二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成ja ...

  7. Springboot21 整合redis、利用redis实现消息队列

    1 前提准备 1.1 创建一个springboot项目 技巧01:本博文基于springboot2.0创建 1.2 安装redis 1.2.1 linux版本 参考博文 1.2.2 windows版本 ...

  8. 微服务架构-利用Redis特性进行业务解耦

    背景:     接着上篇文章来,上篇文章讲的是如何利用ApplicationContext的事件机制来达到业务解耦,而且这只能作用在单体应用中.在当下这么盛行的微服务架构中,想要再利用此方案做业务解耦 ...

  9. 预热一下吧《实现Redis消息队列》

    应用场景 为什么要用redis?二进制存储.java序列化传输.IO连接数高.连接频繁 一.序列化 这里编写了一个java序列化的工具,主要是将对象转化为byte数组,和根据byte数组反序列化成ja ...

随机推荐

  1. JS 返回上一页并刷新代码整理

    一:JS 重载页面,本地刷新,返回上一页: <a href="javascript:history.go(-1)">返回上一页</a> <a href ...

  2. Beta冲刺 2

    前言 队名:拖鞋旅游队 组长博客:https://www.cnblogs.com/Sulumer/p/10104842.html 作业博客:https://edu.cnblogs.com/campus ...

  3. mysql 5.7安装图解 mysql 5.7图文安装完整教程

    今天给搭建分享一个教程,mysql 5.7的安装操作,这里呢我叫大家怎么用二进制去安装mysql,其实在大多数的生产环境中使用二进制预编译的安装方式是最多了,下面大家跟着我的步骤去尝试着安装下吧. 先 ...

  4. swoole架构分析

    swoole的进程/线程结构 结构图如下: swoole主要由Master进程(主进程)和Manager进程配合使用完成其功能. Master进程 是一个多线程的程序.其中有一组很重要的线程,称之为R ...

  5. 2017-10-6模拟赛T3 丝(filament)

    题目 题解 20分实在想不到是什么做法…… 40分做法,从小到大枚举最小循环节长度,O(n) check即可,总复杂度O(n^2). 100分做法: 看到数据范围,T*n<=10^6,可知这题需 ...

  6. [转载] java多线程总结(一)

    转载自:http://www.cnblogs.com/lwbqqyumidi/p/3804883.html 作者:Windstep 多线程作为Java中很重要的一个知识点,在此还是有必要总结一下的. ...

  7. C16记技术服务支持

    1.首页笔记:可以通过点击加号添加笔记的分类,还可以查看最近的10条笔记 2.图形:可以通过查看笔记的比例来分析自己最近的状况 3.快速添加笔记:点击添加笔记能够直接进行笔记 4.时间轴:能够通过文字 ...

  8. VS2017 nlog源码查看报错

    最近下载nlog的源码学习,打开解决方案以后无法编译. C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\Sd ...

  9. MySQL80修改密码

    mysql> update user set password=password('123') where user='root' and host='localhost'; ERROR 106 ...

  10. ios 传递JSON串过去 前面多了个等号

    先说下我的问题 后台让我这边把请求的参数弄成一个实体转化成 json 串放body里传给他,当然header也有设置,提前设置好了, 但是后来了解 所谓的把实体转成json串的本质就是先把实体用run ...