Maison base de données Redis Comment utiliser PHP+Redis pour résoudre le problème de la survente de produits en cas de concurrence élevée

Comment utiliser PHP+Redis pour résoudre le problème de la survente de produits en cas de concurrence élevée

May 26, 2023 pm 03:31 PM
php redis

Pour certains sites e-commerce ayant un certain nombre d'utilisateurs, s'ils utilisent simplement des bases de données relationnelles (comme MySQL, Oracle) pour des achats urgents, la pression sur la base de données sera très forte, et si le verrouillage de la base de données est mal utilisé, le mécanisme entraînera également le problème des produits et des coupons survendus. Mon entreprise a également rencontré le même problème. Le problème s'est produit lorsque les coupons ont été achetés en trop grande quantité. Après que le problème soit survenu, nous avons commencé à réfléchir à des moyens de résoudre le problème. Comme j'utilise beaucoup Redis, je prévois d'utiliser Redis pour résoudre ce problème. . Utilisez les fonctionnalités de haute performance et de transaction de Redis pour résoudre le problème des coupons en ligne récupérés par surstock. Ci-dessous, je donne la première version du pseudo-code que j'ai temporairement résolu ce problème, avec certains détails supprimés :

/**
 * 抢优惠券(秒杀)
 * @param int $couponId 商品ID
 * @param int $uid 用户ID
 * @return bool
 */
function secKill($couponId, $uid)
{
    //1.初始化Redis连接
    $redis = new Redis();
    if (!$redis->connect('127.0.0.1', 6379)) {
        trigger_error('Redis连接出错!!!', E_USER_ERROR);
    } else {
        echo &#39;连接正常<br>&#39;;
    }

    //秒杀商品的库存key
    $key = &#39;secKill:&#39;.$couponId.&#39;:stock&#39;;
    $redis->watch($key);

    //获取库存
    $stock = $redis->get($key);

    //秒杀未开始,表示库存为null
    if (!$stock && !is_numeric($stock)) {
        echo &#39;秒杀未开始&#39;;
        return false;
    }

    //判断库存,如果库存大于0,则减库存,将该成功秒杀用户加入哈希表,如果小于等于0,秒杀结束
    if ($stock <= 0) {
        echo &#39;秒杀已结束&#39;;
        return false;
    }

    //用户已经成功秒杀过一次了,不允许再次参与秒杀
    if ($redis->sIsMember(&#39;secKill:&#39;.$couponId.&#39;:uid&#39;, $uid)) {
        echo &#39;秒杀失败&#39;;
        return false;
    }

    //代码走到这里,说明该用户是第一次参与秒杀,将库存减一,然后把这个人放到已抢到的集合表
    $redisMulti = $redis->multi();
    $redisMulti->decr($key);
    $redisMulti->sAdd(&#39;secKill:&#39;.$couponId.&#39;:uid&#39;, $uid);
    $result = $redisMulti->exec();

    if (empty($result)) {//事务被取消
        echo &#39;秒杀失败&#39;;
        return false;
    }

    //抢券成功,将优惠券ID和UID放入到队列中,由一个单独的进程队列来消费队列里的数据,向用户推送抢到的优惠券
    $redis->lPush(&#39;couponOrder&#39;, $couponId.&#39;+&#39;.$uid);

    return true;
}

$couponId = 11211;
$uid      = mt_rand(1, 100);
secKill($couponId, $uid);
Copier après la connexion
#. 🎜 🎜#Tout d'abord, j'ai simulé la définition de l'inventaire des coupons avec l'ID de coupon 11211 à 10.

Comment utiliser PHP+Redis pour résoudre le problème de la survente de produits en cas de concurrence élevée

Ensuite, nous utilisons l'outil ab pour simuler 1000 requêtes et 50 simultanéités pour tester

ab -n 1000 -c 50 www.test.com/
Copier après la connexion
Ensuite nous utilisons Redis Desktop Manager pour afficher certains résultats Redis

couponOrder Il y a déjà 10 informations utilisateur dans la file d'attente

Comment utiliser PHP+Redis pour résoudre le problème de la survente de produits en cas de concurrence élevée

et il y a des réductions Le reste le nombre de coupons est également 0, ce n'est plus un nombre négatif

Comment utiliser PHP+Redis pour résoudre le problème de la survente de produits en cas de concurrence élevée

En même temps, les informations UID de 10 utilisateurs sont également enregistrées dans le coupon utilisateur collection.

Comment utiliser PHP+Redis pour résoudre le problème de la survente de produits en cas de concurrence élevée

La chaîne de codes ci-dessus résout deux problèmes :

  • résout le problème instantané A un grand nombre de requêtes ont causé beaucoup de pression sur la base de données et le trafic a été intercepté dans la couche de cache Redis

  • Résolu le problème des coupons récupérés en raison d'un excès Inventaire# 🎜🎜#

  • Cependant, ce code présente également certains problèmes :

    n'utilise pas le pool de connexion Redis et le crée fréquemment Le nouveau redis a un certain impact sur les performances
  1. En raison de l'utilisation de transactions, un seul utilisateur réussira à récupérer le coupon dans chaque demande simultanée, et les autres utilisateurs dans la demande simultanée, tout échouera et vous ne pourrez qu'attendre la deuxième simultanéité
  2. C'est aussi un problème d'inventaire causé par la transaction s'il y a 10 produits. et 1 000 requêtes à chaque fois, la simultanéité sera de 200. 5 requêtes simultanées complèteront 1 000 requêtes, mais seuls 5 utilisateurs réussiront à les récupérer. S'il n'y a pas de requêtes ultérieures, il restera 5 copies dans l'inventaire
  3. #. 🎜🎜#

    #🎜 🎜#Astuce : Dans la file d'attente de consommation, si le coupon ne parvient pas à être émis, assurez-vous de l'enregistrer immédiatement et d'informer le responsable des opérations par SMS pour voir s'il peut être renvoyé ou poussé manuellement à l’utilisateur via l’arrière-plan.

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!

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

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Repo: Comment relancer ses coéquipiers
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: Comment obtenir des graines géantes
3 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
Combien de temps faut-il pour battre Split Fiction?
3 Il y a quelques semaines By DDD

Tags d'article chaud

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian Dec 24, 2024 pm 04:42 PM

Guide d'installation et de mise à niveau de PHP 8.4 pour Ubuntu et Debian

Date et heure de CakePHP Date et heure de CakePHP Sep 10, 2024 pm 05:27 PM

Date et heure de CakePHP

Configuration du projet CakePHP Configuration du projet CakePHP Sep 10, 2024 pm 05:25 PM

Configuration du projet CakePHP

Téléchargement de fichiers CakePHP Téléchargement de fichiers CakePHP Sep 10, 2024 pm 05:27 PM

Téléchargement de fichiers CakePHP

Routage CakePHP Routage CakePHP Sep 10, 2024 pm 05:25 PM

Routage CakePHP

Discuter de CakePHP Discuter de CakePHP Sep 10, 2024 pm 05:28 PM

Discuter de CakePHP

Comment configurer Visual Studio Code (VS Code) pour le développement PHP Comment configurer Visual Studio Code (VS Code) pour le développement PHP Dec 20, 2024 am 11:31 AM

Comment configurer Visual Studio Code (VS Code) pour le développement PHP

Guide rapide CakePHP Guide rapide CakePHP Sep 10, 2024 pm 05:27 PM

Guide rapide CakePHP

See all articles