Rumah  >  Artikel  >  pangkalan data  >  Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi

Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi

WBOY
WBOYke hadapan
2023-05-26 15:31:061749semak imbas

Untuk sesetengah tapak web e-dagang dengan bilangan pengguna tertentu, jika mereka hanya menggunakan pangkalan data hubungan (seperti MySQL, Oracle) untuk pembelian tergesa-gesa, tekanan pada pangkalan data akan menjadi sangat hebat, dan jika mekanisme kunci pangkalan data adalah tidak digunakan dengan betul, , ia juga akan membawa kepada masalah produk dan kupon terlebih jual. Syarikat saya juga menghadapi masalah yang sama Masalahnya berlaku apabila kupon terlalu dibeli Selepas masalah berlaku, kami mula memikirkan cara untuk menyelesaikan masalah ini. Oleh kerana saya banyak menggunakan redis . Gunakan ciri prestasi tinggi dan transaksi redis untuk menyelesaikan masalah kupon dalam talian yang diambil oleh stok berlebihan Di bawah saya memberikan versi pertama kod pseudo yang saya selesaikan sementara masalah ini, dengan beberapa butiran dialih keluar:

/**
 * 抢优惠券(秒杀)
 * @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);

Mula-mula, saya mensimulasikan menetapkan inventori kupon dengan ID kupon 11211 hingga 10.

Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi

Kemudian, kami menggunakan alat ab untuk mensimulasikan 1000 permintaan dan 50 konkurensi untuk menguji

ab -n 1000 -c 50 www.test.com/

Kemudian kami menggunakan Redis Desktop Manager untuk melihat beberapa Redis Result

Sudah ada 10 maklumat pengguna dalam baris gilir kuponOrder

Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi

Dan baki bilangan kupon juga ialah 0, bukan lagi nombor negatif

Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi

Pada masa yang sama, maklumat UID 10 pengguna juga disimpan dalam koleksi kupon pengguna.

Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi

Rentetan kod di atas menyelesaikan dua masalah:

  • Ia menyelesaikan masalah sejumlah besar pertanyaan segera kepada pangkalan data menyebabkan banyak kerosakan pada pangkalan data. Masalah tekanan tinggi, trafik dipintas dalam lapisan cache redis

  • Menyelesaikan masalah kupon yang diambil oleh stok berlebihan

Walau bagaimanapun, Kod ini juga mempunyai masalah tertentu:

  1. Kolam sambungan redis tidak digunakan dan penciptaan redis baharu yang kerap mempunyai kesan prestasi tertentu

  2. Ia masih merupakan transaksi Masalah inventori yang terhasil ialah jika terdapat 10 produk dan 1,000 permintaan setiap satu mempunyai 200 permintaan serentak, 1,000 permintaan akan diselesaikan dengan 5 permintaan serentak, tetapi hanya 5 pengguna yang akan berjaya merebutnya tidak ada permintaan berikutnya, akan ada Akibatnya, masih terdapat 5 salinan dalam stok
  3. Petua: Dalam baris gilir penggunaan, jika kupon gagal dikeluarkan, pastikan anda merekodkan ia serta-merta dan maklumkan pengurus operasi melalui mesej teks untuk melihat sama ada ia boleh dikeluarkan semula atau Ditolak kepada pengguna melalui penyasaran manual di latar belakang.

Atas ialah kandungan terperinci Cara menggunakan PHP+Redis untuk menyelesaikan masalah penjualan berlebihan produk di bawah keselarasan tinggi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:yisu.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam