好久没来整理文章了,闲了没事写篇文章记录下php+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

2,项目中实际使用redis

  2.1,第一步配置redis参数如下,redis安装的默认端口为6379: 

<?php
/* 数据库配置 */
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队列已释放!");
}
}

  走到此处的时候秒杀的核心基本就完了,细节还需要自己在去完善,像购物车这边的处理还有订单的处理,好吧开始跑程序利用apache自身的ab可以进行简单的模拟并发测试如下:

跑起来,我擦跑步起来redis没有任何反应,此时还少一步重要的步骤就是开启redis服务,请根据自己的系统下一个redisbin_x32或者redisbin_x64的redis服务管理工具,点击redis-server.exe,ok至此全部完成如下图:

thinkphp+redis实现秒杀功能的更多相关文章

  1. thinkphp+redis实现秒杀功能(转)

    1,安装redis,根据自己的php版本安装对应的redis扩展(此步骤简单的描述一下) 1.1,安装 php_igbinary.dll,php_redis.dll扩展此处需要注意你的php版本如图: ...

  2. thinkphp+redis实现秒杀,缓存等功能

    秒杀是商城常见功能  php+redis是最常见的秒杀功能 1,安装redis,根据自己的php版本安装对应的redis扩展 首先查看phpinfo();php环境信息 2,下载redis https ...

  3. php结合redis实现秒杀功能

    <?php 第一种,简单实现 $conn=mysql_connect("localhost","big","123456"); if( ...

  4. 电商项目中使用Redis实现秒杀功能

    参与过抢购活动就知道,很明显的一点是商即便商品实际没有了也是可以下单成功的,但是在支付的时候会提示你商品没有了. 实现原理:list双向链表 使用redis队列,因为pop操作是原子的,即使有很多用户 ...

  5. php+redis实现电商秒杀功能

    这一次总结和分享用Redis实现分布式锁来完成电商的秒杀功能.先扯点个人观点,之前我看了一篇博文说博客园的文章大部分都是分享代码,博文里强调说分享思路比分享代码更重要(貌似大概是这个意思,若有误请谅解 ...

  6. Redis事务和实现秒杀功能的实现

    今天带着学生学习了Redis的事务功能,Redis的事务与传统的关系型数据库(如MySQL)有所不同,Redis的事务不能回滚. Redis中使用multi.exec.discard.watch.un ...

  7. Redis分布式锁实现简单秒杀功能

    这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...

  8. spring boot:redis+lua实现生产环境中可用的秒杀功能(spring boot 2.2.0)

    一,秒杀需要具备的功能: 秒杀通常是电商中用到的吸引流量的促销活动方式 搭建秒杀系统,需要具备以下几点: 1,限制每个用户购买的商品数量,(秒杀价格为吸引流量一般会订的很低,不能让一个用户全部抢购到手 ...

  9. 秒杀功能压测 jmeter--------重要!!!

    线程组里面有三个接口请求,依次为:显示商品列表.登录秒杀平台账户.进行秒杀 对线程组用5000个线程循环10次 设置一下默认配置,之后就不用反复填写了 设置配置文件这个具体功能就是读text文件并且设 ...

随机推荐

  1. java集合使用——HashMap

    在map中插入.删除和定位元素时,HashMap是最好的选择.如果要按照自然顺序或自定义顺序遍历(获取所有元素),那么treemap更好一些. 第一:构造和添加元素 HashMap map = new ...

  2. GitHub+hexo to Blog

    title: GitHub+hexo to Blog date: 2014-12-26 09:44:53 tags: hexo, github --- 摘要 一直想要一个自己的博客,不过一直怯于对网站 ...

  3. im2uint8函数分析

    环境:Win7 64位 + Matlab R2010a 本次分析的函数为im2uint8,这个函数在图像处理中要用到,主要把图像数据类转换到uint8 uint8函数有效的输入的图像数据类为:logi ...

  4. (原)ubuntu14手动安装matplotlib1.5

    转载请注明出处: http://www.cnblogs.com/darkknightzh/p/5681059.html 参考网址: http://matplotlib.org/users/instal ...

  5. 禁用谷歌字体解决WordPress访问速度过慢问题

    这几天打开网站的时候发现突然变慢了,一直等待加载fonts.googleapis.com,搜索了一下发现很多wordpress网站都出现了 这种现象,原来是因为今日谷歌全线退出中国,貌似谷歌.Gmai ...

  6. 数据挖掘(data mining),机器学习(machine learning),和人工智能(AI)的区别是什么? 数据科学(data science)和商业分析(business analytics)之间有什么关系?

    本来我以为不需要解释这个问题的,到底数据挖掘(data mining),机器学习(machine learning),和人工智能(AI)有什么区别,但是前几天因为有个学弟问我,我想了想发现我竟然也回答 ...

  7. QWidget可以设置QStyle,它可以绘制很多东西(具体内容没研究,待续)

    QStyle * QWidget::style() const See also QWidget::setStyle(), QApplication::setStyle(), and QApplica ...

  8. 【Xamarin挖墙脚系列:常用的Mac 命令】

    通俗点说Mac 跟Linux的爹都是Unix,他们都加入了标准的Shell命令工具,bash 所以俩系统中的命令基本通用 Linux下的操作手册,本人自己整理了一份.呵呵~~~~ 还可以使用客户端远程 ...

  9. EditText获取焦点监听事件_EditText获取和失去焦点操作

    今天在做搜索框的时候.遇到需要获取焦点之后做一些事情.实现方法也很简单.那就是绑定OnFocusChangeListener事件.实现 onFocusChange(View v, boolean ha ...

  10. vc++ ODBC

    http://book.51cto.com/art/200807/80054.htm http://www.cnblogs.com/xrong/archive/2013/04/14/3020240.h ...