thinkphp+redis+队列
1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下)
1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图:
1.2,php.ini文件新增 extension=php_igbinary.dll;extension=php_redis.dll两处扩展
ok此处已经完成第一步redis环境搭建完成看看phpinfo
项目中实际使用redis
2.1,第一步配置redis参数如下,redis安装的默认端口为6379:
/* 数据库配置 */
return array(
'DATA_CACHE_PREFIX' => 'Redis_',//缓存前缀
'DATA_CACHE_TYPE'=>'Redis',//默认动态缓存为Redis
'DATA_CACHE_TIMEOUT' => false,
'REDIS_RW_SEPARATE' => true, //Redis读写分离 true 开启
'REDIS_HOST'=>'127.0.0.1', //redis服务器ip,多台用逗号隔开;读写分离开启时,第一台负责写,其它[随机]负责读;
'REDIS_PORT'=>'6379',//端口号
'REDIS_TIMEOUT'=>'300',//超时时间
'REDIS_PERSISTENT'=>false,//是否长连接 false=短连接
'REDIS_AUTH'=>'',//AUTH认证密码
);
?>
2.2,实际函数中使用redis:
/**
* redis连接
* @access private
* @return resource
* @author bieanju
*/
private function connectRedis(){
$redis=new \Redis();
$redis->connect(C("REDIS_HOST"),C("REDIS_PORT"));
return $redis;
}
2.3,秒杀的核心问题是在大并发的情况下不会超出库存的购买,这个就是处理的关键所以思路是第一步在秒杀类的先做一些基础的数据生成:
//现在初始化里面定义后边要使用的redis参数
public function _initialize(){
parent::_initialize();
$goods_id = I("goods_id",'0','intval');
if($goods_id){
$this->goods_id = $goods_id;
$this->user_queue_key = "goods_".$goods_id."_user";//当前商品队列的用户情况
$this->goods_number_key = "goods".$goods_id;//当前商品的库存队列
}
$this->user_id = $this->user_id ? $this->user_id : $_SESSION['uid'];
}
2.4,第二步就是关键所在,用户在进入商品详情页前先将当前商品的库存进行队列存入redis如下:
/**
* 访问产品前先将当前产品库存队列
* @access public
* @author bieanju
*/
public function _before_detail(){
$where['goods_id'] = $this->goods_id;
$where['start_time'] = array("lt",time());
$where['end_time'] = array("gt",time());
$goods = M("goods")->where($where)->field('goods_num,start_time,end_time')->find();
!$goods && $this->error("当前秒杀已结束!");
if($goods['goods_num'] > $goods['order_num']){
$redis = $this->connectRedis();
$getUserRedis = $redis->hGetAll("{$this->user_queue_key}");
$gnRedis = $redis->llen("{$this->goods_number_key}");
/* 如果没有会员进来队列库存 */
if(!count($getUserRedis) && !$gnRedis){
for ($i = 0; $i < $goods['goods_num']; $i ++) {
$redis->lpush("{$this->goods_number_key}", 1);
}
}
$resetRedis = $redis->llen("{$this->goods_number_key}");
if(!$resetRedis){
$this->error("系统繁忙,请稍后抢购!");
}
}else{
$this->error("当前产品已经秒杀完!");
} }
接下来要做的就是用ajax来异步的处理用户点击购买按钮进行符合条件的数据进入购买的排队队列(如果当前用户没在当前产品用户的队列就进入排队并且pop一个库存队列,如果在就抛出,)
/**
* 抢购商品前处理当前会员是否进入队列
* @access public
* @author bieanju
*/
public function goods_number_queue(){
!$this->user_id && $this->ajaxReturn(array("status" => "-1","msg" => "请先登录"));
$model = M("flash_sale");
$where['goods_id'] = $this->goods_id;
$goods_info = $model->where($where)->find();
!$goods_info && $this->error("对不起当前商品不存在或已下架!");
/* redis 队列 */
$redis = $this->connectRedis();
/* 进入队列 */
$goods_number_key = $redis->llen("{$this->goods_number_key}");
if (!$redis->hGet("{$this->user_queue_key}", $this->user_id)) {
$goods_number_key = $redis->lpop("{$this->goods_number_key}");
} if($goods_number_key){
// 判断用户是否已在队列
if (!$redis->hGet("{$this->user_queue_key}", $this->user_id)) {
// 插入抢购用户信息
$userinfo = array(
"user_id" => $this->user_id,
"create_time" => time()
);
$redis->hSet("{$this->user_queue_key}", $this->user_id, serialize($userinfo));
$this->ajaxReturn(array("status" => "1"));
}else{
$modelCart = M("cart");
$condition['user_id'] = $this->user_id;
$condition['goods_id'] = $this->goods_id;
$condition['prom_type'] = 1;
$cartlist = $modelCart->where($condition)->count();
if($cartlist > 0){
$this->ajaxReturn(array("status" => "2"));
}else{ $this->ajaxReturn(array("status" => "1")); } } }else{
$this->ajaxReturn(array("status" => "-1","msg" => "系统繁忙,请重试!"));
}
}
附加一个调试的函数,删除指定队列值:
public function clearRedis(){
set_time_limit(0);
$redis = $this->connectRedis();
//$Rd = $redis->del("{$this->user_queue_key}");
$Rd = $redis->hDel("goods49",'用户id'');
$a = $redis->hGet("goods_49_user", '用户id');
if(!$a){
dump($a);
} if($Rd == 0){
exit("Redis队列已释放!");
}
}
thinkphp+redis+队列的更多相关文章
- 详解thinkphp+redis+队列的实现代码
1,安装Redis,根据自己的PHP版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图: ...
- [bigdata] 使用Redis队列来实现与机器无关的Job提交与执行 (python实现)
用例场景: 定时从远程多台机器上下载文件存入HDFS中.一开始采用shell 一对一的方式实现,但对于由于网络或者其他原因造成下载失败的任务无法进行重试,且如果某台agent机器down机,将导致它对 ...
- 我心中的核心组件~MSMQ与Redis队列
回到目录 这个文章其实是我心中的核心组件的第七回,确实在时间上有些滞后了,但内容并不滞后!本文MSMQ只是个引题,我确实不太想说它,它是微软自己集成的一套消息队列,寄宿在Window服务里,稳定性十在 ...
- c#之Redis队列在邮件提醒中的应用
场景 有这样一个场景,一个邮件提醒的windows服务,获取所有开启邮件提醒的用户,循环获取这些用户的邮件,发送一条服务号消息.但问题来了,用户比较少的情况下,轮询一遍时间还能忍受,如果用户多了,那用 ...
- c#之Redis队列
摘要 这两天一直在考虑redis队列:一个生产者,多个消费者的情况,这里弄了一个demo进行测试. 一个例子 关于如何引用Redisclient 可以参考之前的这篇文章:c#之Redis实践list, ...
- redis队列的实现
redis中文官网:http://www.redis.cn/ 关于redis队列的实现方式有两种: 1.生产者消费者模式. 2.发布者订阅者模式. 详解: 1.生产者消费者模式. 普通版本: 比如一个 ...
- (3)redis队列功能
Redis队列功能介绍 List 常用命令: Blpop删除,并获得该列表中的第一元素,或阻塞,直到有一个可用 Brpop删除,并获得该列表中的最后一个元素,或阻塞,直到有一个可用 Brpoplpus ...
- 转载:【高并发简单解决方案 | 靠谱崔小拽 】redis队列缓存 + mysql 批量入库 + php离线整合
需求背景:有个调用统计日志存储和统计需求,要求存储到mysql中:存储数据高峰能达到日均千万,瓶颈在于直接入库并发太高,可能会把mysql干垮. 问题分析 思考:应用网站架构的衍化过程中,应用最新的框 ...
- thinkphp+redis实现秒杀功能
好久没来整理文章了,闲了没事写篇文章记录下php+redis实现商城秒杀功能. 1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbi ...
随机推荐
- oracle 表空间总结
表空间总结 一.认识表空间 1:表空间概念: 表空间是数据库中最大的逻辑单位,Oracle数据库采用表空间将相关的逻辑组件组合在一起,一个Oracle数 ...
- GNU Radio: Synchronization and MIMO Capability with USRP Devices
Application Note Synchronization and MIMO Capability with USRP Devices Ettus Research Introduction S ...
- 【linux】centos6.5搭建svn
1.检查是否已安装 rpm -qa subversion 如果要卸载旧版本: yum remove subversion 2.安装 yum install subversion PS:yum inst ...
- (转)2009-05-25 22:12 Outlook2007选择发送帐号
本文转载自:http://hi.baidu.com/vugwggogodaenqe/item/c95c6d019457a2d873e676ec outlook2007可以用程序选择发送帐号,其他的版本 ...
- win7右下角的网络连接图标不见了~终极必杀技
1.打开程序管理器(ctrl+alt+delete) 2.在进程那里找到"explorer.exe",然后按结束进程(此时工具栏会消失) 3.然后在文件(程序管理器左上角),点击& ...
- 机器学习中的python常用函数
glob模块 说明: 1.glob是python自己带的一个文件操作相关模块,用它可以查找符合自己目的的文件,就类似于Windows下的文件搜索, 支持通配符操作 *.?.[] 这三个通配符,*代表0 ...
- JSON格式化工具推荐
JSON以其独特的简洁方便及与Javscript的无缝集成在WEB2.0时瓦风靡全球. 不过做为开发者,当看到一段很长的未格式化的JSON代码时,你会不会感到头晕? {"meta&quo ...
- canvas设置阴影
canvas设置阴影 属性 shadowOffsetX = float 阴影向右偏移量 shadowOffsetY = float 阴影向下偏移量 shadowBlur = float 阴影模糊效果 ...
- 725. Split Linked List in Parts
▶ 将一个单链表拆分为长度尽量接近的 k 段 ● 自己的代码,12 ms ■ 记链表长度为 count,目标段数为 k,quo = count / k,mod = count % k,part = m ...
- could not be installed at this time
无法下载应用 此时无法安装 Unable to Download App ''App" could not be installed at this time 编译程序的时候,Target ...