Analyse de cas d'utilisation de php+redis pour implémenter la fonction de vente flash du centre commercial (avec code)

php中世界最好的语言
Libérer: 2023-03-26 18:56:01
original
2224 Les gens l'ont consulté

Cette fois, je vais vous apporter une analyse de cas (avec code) de php+redis implémentant la fonction de vente flash du centre commercial. Quelles sont les précautions pour que php+redis implémente la fonction de vente flash du centre commercial. Voici un cas pratique. Jetons un coup d'oeil.

1. Installez redis et installez l'extension redis correspondante en fonction de votre propre version de PHP (décrivez brièvement cette étape)

1.1. Installez php_igbinary.dll, l'extension php_redis.dll nécessite votre attention ici. La version de php est la suivante :

Le fichier 1.2.php.ini ajoute extension=php_igbinary.dll;extension=php_redis.dll deux extensions

ok Le la première étape de configuration de l'environnement redis est terminée. Jetez un œil à phpinfo

2.1. La première étape consiste à configurer redis. Les paramètres sont les suivants. Le port par défaut pour l'installation de redis est 6379 :

2.2. Utilisez redis dans la fonction réelle :
<?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认证密码 
);
?>
Copier après la connexion

2.3. . Le problème principal du flash kill est dans le cas d'une grande concurrence. L'achat ne dépassera pas l'inventaire, c'est la clé du traitement, donc l'idée est de générer des données de base dans la catégorie des ventes flash dans la première étape :
/**
    * redis连接
    * @access private
    * @return resource
    * @author bieanju
    */
  private function connectRedis(){
    $redis=new \Redis();
    $redis->connect(C("REDIS_HOST"),C("REDIS_PORT"));    
    return $redis;
  }
Copier après la connexion

2.4. La deuxième étape est la clé, l'utilisateur est Avant d'entrer dans la page
//现在初始化里面定义后边要使用的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'];   
  }
Copier après la connexion
détails du produit

, mettez l'inventaire actuel du produit en file d'attente et stockez-le dans Redis comme suit :

La prochaine chose à faire est d'utiliser ajax pour traiter de manière asynchrone le clic de l'utilisateur sur le bouton d'achat. Les données qui remplissent les conditions entrent dans la file d'attente d'achat (si l'utilisateur actuel n'est pas dans la file d'attente de l'utilisateur actuel du produit, il entre dans la file d'attente et affiche une file d'attente d'inventaire, si c'est le cas, il la jette) :
/**
  * 访问产品前先将当前产品库存队列
  * @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("当前产品已经秒杀完!");
    }
     
  }
Copier après la connexion

Attachez une fonction de débogage, supprimez la valeur de file d'attente spécifiée :
/**
   * 抢购商品前处理当前会员是否进入队列
   * @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" => "系统繁忙,请重试!"));
    }
  }
Copier après la connexion

Lorsque vous Arrivez ici, le cœur de la vente flash est pratiquement terminé. Les détails doivent encore être améliorés par vous-même, comme le traitement du panier et le traitement des commandes. D'accord, commençons à exécuter le programme et utilisons le propre ab d'Apache. effectuez un simple test de concurrence simulée comme suit :
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队列已释放!");      
     }
   }
Copier après la connexion

Lorsque je l'exécute, redis ne répond pas du tout. Pour le moment, il n'y a pas de réponse. démarrez le service redis. Veuillez utiliser l'outil de gestion du service redisbin_x32 ou redisbin_x64 en fonction de votre système, cliquez sur redis-server.exe, puis tout est terminé comme indiqué ci-dessous :

Je pense que vous maîtrisez la méthode après avoir lu le cas dans cet article. Pour des informations plus intéressantes, veuillez prêter attention aux autres articles connexes sur le site Web chinois de php !

Lecture recommandée :

Analyse de l'utilisation du cas d'utilisation du chiffrement, du déchiffrement et de l'interface de développement RSA de PHP


Analyse du cas d'utilisation des connexions longues PHP

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal