详解thinkphp+redis+队列的实现代码
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了详解thinkphp+redis+队列的实现代码,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4763字,纯文字阅读大概需要7分钟。
内容图文
![详解thinkphp+redis+队列的实现代码](/upload/InfoBanner/zyjiaocheng/858/b9d062a5f7ad4de18fd952f86b1a5e0a.jpg)
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:
1234567891011121314 | <?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:
1234567891011 | /** ?? * 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,秒杀的核心问题是在大并发的情况下不会超出库存的购买,这个就是处理的关键所以思路是第一步在秒杀类的先做一些基础的数据生成:
1234567891011 | //现在初始化里面定义后边要使用的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如下:
123456789101112131415161718192021222324252627282930 | /** * 访问产品前先将当前产品库存队列 * @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一个库存队列,如果在就抛出,):
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849 | /** ?? * 抢购商品前处理当前会员是否进入队列 ?? * @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" => "系统繁忙,请重试!" )); ?? } ? } |
附加一个调试的函数,删除指定队列值:
1234567891011121314 | 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+队列的实现代码所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。