>  기사  >  백엔드 개발  >  Thinkphp 및 redis+queue 구현 예제 코드(그림)

Thinkphp 및 redis+queue 구현 예제 코드(그림)

黄舟
黄舟원래의
2017-08-22 09:26:062253검색

이 글은 thinkphp+redis+queue의 구현 코드를 주로 소개하고 있는데, 편집자가 보기에는 꽤 좋다고 생각해서 지금부터 참고용으로 올려보겠습니다. 편집기를 따라 살펴보겠습니다

1. Redis를 설치하고 PHP 버전에 따라 해당 Redis 확장을 설치합니다(이 단계는 간략하게 설명됩니다). php_igbinary.dll 확장은 여기에서 주의해야 합니다. 귀하의 PHP 버전은 그림과 같습니다:

 

1.2, php.ini 파일에는 두 개의 새로운 확장자가 있습니다: Extension=php_igbinary.dll; Extension=php_redis.dll

ok Redis 환경 구축의 첫 번째 단계는 다음과 같습니다. phpinfo

이 프로젝트는 실제로 redis

2.1을 사용합니다. Redis 설치의 기본 포트는 6379입니다.

<?php
/* 数据库配置 */
return array(
 &#39;DATA_CACHE_PREFIX&#39; => &#39;Redis_&#39;,//缓存前缀
 &#39;DATA_CACHE_TYPE&#39;=>&#39;Redis&#39;,//默认动态缓存为Redis
 &#39;DATA_CACHE_TIMEOUT&#39; => false,
 &#39;REDIS_RW_SEPARATE&#39; => true, //Redis读写分离 true 开启
 &#39;REDIS_HOST&#39;=>&#39;127.0.0.1&#39;, //redis服务器ip,多台用逗号隔开;读写分离开启时,第一台负责写,其它[随机]负责读;
 &#39;REDIS_PORT&#39;=>&#39;6379&#39;,//端口号
 &#39;REDIS_TIMEOUT&#39;=>&#39;300&#39;,//超时时间
 &#39;REDIS_PERSISTENT&#39;=>false,//是否长连接 false=短连接
 &#39;REDIS_AUTH&#39;=>&#39;&#39;,//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",&#39;0&#39;,&#39;intval&#39;);  
  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[&#39;uid&#39;];  
 }

2.4, 두 번째 단계는 제품 세부 정보 페이지에 들어가기 전에 사용자가 현재 제품 재고 및 매장을 대기열에 추가하는 것입니다.


 /**
 * 访问产品前先将当前产品库存队列
 * @access public
 * @author bieanju
 */
 public function _before_detail(){
  $where[&#39;goods_id&#39;] = $this->goods_id;
  $where[&#39;start_time&#39;] = array("lt",time());
  $where[&#39;end_time&#39;] = array("gt",time());
  $goods = M("goods")->where($where)->field(&#39;goods_num,start_time,end_time&#39;)->find();
  !$goods && $this->error("当前秒杀已结束!");
  if($goods[&#39;goods_num&#39;] > $goods[&#39;order_num&#39;]){
   $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[&#39;goods_num&#39;]; $i ++) {
     $redis->lpush("{$this->goods_number_key}", 1);
    }
   }
   $resetRedis = $redis->llen("{$this->goods_number_key}");
   if(!$resetRedis){
    $this->error("系统繁忙,请稍后抢购!");
   }
  }else{
   $this->error("当前产品已经秒杀完!");
  }
   
 }

다음으로 할 일은 ajax를 사용하여 비동기식으로 수행하는 것입니다. 사용자의 구매 버튼 클릭을 처리하여 구매 대기열에 적격한 데이터를 입력합니다(현재 사용자가 그렇지 않은 경우). 현재 제품 사용자의 대기열에 대기열을 입력하고 인벤토리 대기열을 팝하고, 그렇다면 버리십시오.):


/**
  * 抢购商品前处理当前会员是否进入队列
  * @access public
  * @author bieanju
  */
 public function goods_number_queue(){
  !$this->user_id && $this->ajaxReturn(array("status" => "-1","msg" => "请先登录"));
  $model = M("flash_sale");
  $where[&#39;goods_id&#39;] = $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[&#39;user_id&#39;] = $this->user_id;
    $condition[&#39;goods_id&#39;] = $this->goods_id;
    $condition[&#39;prom_type&#39;] = 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" => "系统繁忙,请重试!"));
  }
 }

지정된 대기열 값을 삭제하는 디버그 기능을 첨부합니다:

으아악

위 내용은 Thinkphp 및 redis+queue 구현 예제 코드(그림)의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.