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 ...
随机推荐
- thinkphp 模型验证
<?php class FormModel extends Model { // 自动验证设置 /* * 一:自动验证 自动验证的定义是这样的:array(field,rule,message, ...
- 单线程和多线程处理1W条数据对比代码
package study.interview; import java.util.ArrayList; import java.util.HashMap; import java.util.Link ...
- Python基础之文件
输出一行一行的,效率更高 一个任务: 主函数:
- 在eclipse中使用mybatis-generator自动创建代码
1.eclipse中安装插件,地址:http://mybatis.googlecode.com/svn/sub-projects/generator/trunk/eclipse/UpdateSite/ ...
- 交叉编译OpenCV的Android版本
交叉编译OpenCV的Android版本 OpenCV作为一个强大的图像处理库,在Android上也有强大的应用. OpenCV官网提供了SDK的下载,可以直接下载使用 OpenCV官网地址:http ...
- Wasserstein距离 和 Lipschitz连续
EMD(earth mover distance)距离: 在计算机科学与技术中,地球移动距离(EMD)是一种在D区域两个概率分布距离的度量,就是被熟知的Wasserstein度量标准.不正式的说,如果 ...
- MySQL 常用命令行
增加新用户 格式:grant 权限 on 数据库.* to 用户名@登录主机 identified by "密码" 如,增加一个用户user1密码为password1,让其可以在本 ...
- zookeeper 分布式计数器
分布式计数器的思路是:指定一个Zookeeper数据节点作为计数器,多个应用实例在分布式锁的控制下,通过更新该数据节点的内容来实现计数功能. Curator中封装了实现,例如 DistributedA ...
- C#预编译的问题
C#预编译宏并不像C++那样编译之后就不存在了.在UNITY的C#脚本中 #if UNITY_ANDROID && !UNITY_EDITOR AndroidJavaClass jc ...
- WebFont-前端字体
WebFont-前端字体 前端设计时使用了一些不常用的字体,如何在客户的浏览器中正确展示? 解决方案是使用webfont,将字体置于服务端,利用 css 中的font-family进行设置,客户端展现 ...