Maison  >  Article  >  développement back-end  >  Tests PHP à haute concurrence : étude de cas sur la prévention de la survente des stocks

Tests PHP à haute concurrence : étude de cas sur la prévention de la survente des stocks

WBOY
WBOYavant
2022-04-08 09:32:547315parcourir

Dans l'article précédent "Comment empêcher la survente des stocks de produits en cas de concurrence élevée en PHP", nous avons parlé des problèmes liés à la prévention des stocks survendus en cas de concurrence élevée. Jetons un coup d'œil à la prévention de la survente des stocks. Le contenu associé aux tests simultanés, J'espère que cela sera utile à tout le monde.

Tests PHP à haute concurrence : étude de cas sur la prévention de la survente des stocks

Cet article est basé sur le cas de test de "Comment empêcher la survente de l'inventaire de produits en cas de concurrence élevée en PHP". Apprentissage recommandé : "Tutoriel d'apprentissage PHP"

1. Commande ordinaire

Lors des tests simultanés, identifiant de la table du produit = 1 nom = magasin Daohuaxiang Rice = 15

请求总数30 每次10个并发
ab -n 30 -c 10 http://xxxxx.top/code/the_limit/add_order.php

Résultat :

Il y a eu 15 réductions de stock réussies. L'inventaire du magasin a un nombre négatif de -7 8 fois et est jugé comme un inventaire insuffisant (les numéros d'inventaire négatifs sont incorrects et ne sont pas autorisés)

2 Mode non signé

Revenir à la table des produits id =1 nom = Daohuaxiang Rice store =. 15

请求总数30 每次10个并发
ab -n 30 -c 10 http://xxxxx.top/code/the_limit/unsigned.php

Résultat :

Il y a eu 15 réductions de stock réussies. L'inventaire du magasin a montré un nombre négatif de -6, il a été jugé que l'inventaire n'était pas suffisant (les numéros d'inventaire négatifs sont incorrects et interdits).

Le simple fait d'ajouter une mise à jour à l'instruction de requête a peu d'effet sur le verrouillage

3. Transaction MySQL, ligne d'opération de verrouillage

Réajuster à l'identifiant de la table des produits = 1 nom = Daohuaxiang Rice store = 15

请求总数30 每次10个并发
ab -n 30 -c 10 http://xxxxx.top/code/the_limit/ACID.php

Résultat :

Il y a eu 15 réductions de stock réussies, et l'inventaire du magasin n'est pas apparu négatif 15. Il est jugé que l'inventaire est insuffisant (les numéros d'inventaire négatifs sont incorrects et ne sont pas autorisés)

L'effet de l'ajout de transactions ab -n 3000 -c 1000 peut également résister à la concurrence

4. Verrouillage exclusif de fichier non bloquant

  • Formulaire de blocage

  • Formulaire non bloquant

L'effet n'est pas négatif, mais en termes de performances : Transaction > Blocage > Non- blocage

5. file d'attente Redis

Le code est légèrement ajusté par rapport à la version précédente de verrouillage optimiste

<?php
$redis =new Redis();
$redis->connect("127.0.0.1", 6379);
$redis->auth(&#39;PASSWORD&#39;);
$redis->watch(&#39;sales&#39;);//乐观锁 监视作用 set()  初始值0
$sales = $redis->get(&#39;sales&#39;);
//var_dump($sales); exit;

db();
global $con;
// 查询商品信息
//$product_id = 1;
//$sql = "select * from products where id={$product_id}";
//$result = mysqli_query($con, $sql);
//$row = mysqli_fetch_assoc($result);
//$store = $row[&#39;store&#39;];
// 库存
$n = 15;
if ($sales >= $n) {
    insertLog(&#39;库存为0 秒杀失败&#39;);
    exit(&#39;秒杀结束&#39;);
}

//redis开启事务
$redis->multi();
$redis->incr(&#39;sales&#39;); //将 key 中储存的数字值增一 ,如果 key 不存在,那么 key 的值会先被初始化为 0 ,然后再执行 INCR 操作。
$res = $redis->exec(); //成功1 失败0

if ($res) {
    //秒杀成功
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;PASSWORD&#39;,&#39;dev&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }

    $product_id = 1;// 商品ID
    $buy_num = 1;// 购买数量
    sleep(1);

    $sql = "update products set store=store-{$buy_num} where id={$product_id}";

    if (mysqli_query($con, $sql)) {
        echo "秒杀完成";
        insertLog(&#39;恭喜 秒杀成功&#39;);
    }

} else {
    insertLog(&#39;抱歉 秒杀失败&#39;);
    exit(&#39;抢购失败&#39;);
}

function db()
{
    global $con;
    $con = new mysqli(&#39;localhost&#39;,&#39;root&#39;,&#39;WOrd1234.*&#39;,&#39;dev&#39;);
    if (!$con) {
        echo "数据库连接失败";
    }
}

/**
 * 记录日志
 */
function insertLog($content)
{
    global $con;
    $sql = "INSERT INTO `order_log` (content) values(&#39;$content&#39;)";
    mysqli_query($con, $sql);
}
ab -n 30 -c 10 http://xxxxxx.top/code/the_limit/optimistic\ _redis_lock.php

Conclusion finale Donnez la priorité aux défis de concurrence et Redis a de bonnes performances

Apprentissage recommandé : "Tutoriel vidéo 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!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer