Home  >  Article  >  Backend Development  >  Case analysis of using php+redis to implement the flash sale function of the mall (with code)

Case analysis of using php+redis to implement the flash sale function of the mall (with code)

php中世界最好的语言
php中世界最好的语言Original
2018-05-19 10:03:062152browse

This time I will bring you a case analysis of php redis implementing the mall flash sale function (with code). What are the precautions for php redis to implement the mall flash sale function. The following is a practical case, let’s take a look.

1. Install redis and install the corresponding redis extension according to your own PHP version (this step is briefly described)

1.1. Install php_igbinary.dll. The php_redis.dll extension needs attention here. Your php version is as shown below:

##1.2.php.ini file adds extension=php_igbinary.dll;extension=php_redis.dll two extensions

ok The first step of setting up the redis environment has been completed. Take a look at phpinfo

2. The actual use of redis in the project

2.1. The first step is to configure redis The parameters are as follows. The default port for redis installation is 6379:

<?php
/* 数据库配置 */
return array(
  &#39;DATA_CACHE_PREFIX&#39; => '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. Using redis in the actual function:

/**
    * 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. The core problem of flash sales is that the inventory will not be exceeded in the case of large concurrency Purchase, this is the key to processing, so the idea is that the first step is to generate some basic data in the flash sale category:

//现在初始化里面定义后边要使用的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. The second step is the key, the user enters the

product details Before the page, queue the current product inventory and store it in redis as follows:

/**
  * 访问产品前先将当前产品库存队列
  * @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[&#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("当前产品已经秒杀完!");
    }
     
  }
The next thing to do is to use ajax to asynchronously process the user's click on the purchase button to queue up the eligible data for purchase. Queue (if the current user is not in the queue of the current product user, it will enter the queue and pop an inventory queue, if it is, it will be thrown):

/**
   * 抢购商品前处理当前会员是否进入队列
   * @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" => "系统繁忙,请重试!"));
    }
  }
Attach a debugging function to delete the specified queue value:

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队列已释放!");      
     }
   }
When we get here, the core of the flash sale is basically finished. The details still need to be improved by ourselves, such as the processing of the shopping cart and the processing of orders. OK, let’s start running the program and use apache’s own ab. A simple simulated concurrency test is as follows:

When I run it, redis does not respond at all. At this time, there is one important step missing, which is to start the redis service. Please follow your own instructions Under the system, use redisbin_x32 or redisbin_x64 redis service management tool, click redis-server.exe, ok. Now everything is completed as shown below:

I believe you have mastered it after reading the case in this article. For more exciting methods, please pay attention to other related articles on the php Chinese website!

Recommended reading:

PHP’s RSA encryption, decryption and development interface case usage analysis

PHP long connection usage case analysis

The above is the detailed content of Case analysis of using php+redis to implement the flash sale function of the mall (with code). For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn