一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - PHP教程 - PHP+Redis事務解決高并發下商品超賣問題(推薦)

PHP+Redis事務解決高并發下商品超賣問題(推薦)

2021-10-21 12:33itbsl PHP教程

這篇文章主要介紹了PHP+Redis事務解決高并發下商品超賣問題,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下

對于一些有一定用戶量的電商網站,如果只是單純的使用關系型數據庫(如mysql、oracle)來做搶購,對數據庫的壓力是非常大的,而且如果不使用好數據庫的鎖機制,還會導致商品、優惠券超賣的問題。我所在的公司也遇到了同樣的問題,問題發生在優惠券被超量搶購上,在問題發生后我們開始想辦法解決問題,由于自己使用redis比較多,我準備使用redis來解決這個問題。利用redis的高性能和事務特性來解決線上優惠券被超庫存搶購的問題,下面我給出我臨時解決這個問題的第一版的偽代碼,去掉了一些細節:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/**
 * 搶優惠券(秒殺)
 * @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 '連接正常<br>';
 }
 
 //秒殺商品的庫存key
 $key = 'seckill:'.$couponid.':stock';
 $redis->watch($key);
 
 //獲取庫存
 $stock = $redis->get($key);
 
 //秒殺未開始,表示庫存為null
 if (!$stock && !is_numeric($stock)) {
 echo '秒殺未開始';
 return false;
 }
 
 //判斷庫存,如果庫存大于0,則減庫存,將該成功秒殺用戶加入哈希表,如果小于等于0,秒殺結束
 if ($stock <= 0) {
 echo '秒殺已結束';
 return false;
 }
 
 //用戶已經成功秒殺過一次了,不允許再次參與秒殺
 if ($redis->sismember('seckill:'.$couponid.':uid', $uid)) {
 echo '秒殺失敗';
 return false;
 }
 
 //代碼走到這里,說明該用戶是第一次參與秒殺,將庫存減一,然后把這個人放到已搶到的集合表
 //multi(),返回一個redis對象,并進入multi-mode模式,一旦進入multi-mode模式,以后調用的所有方法都會返回相同的對象,
 //直到exec()方法被調用。
 $result = $redis->multi()->decr($key)->sadd('seckill:'.$couponid.':uid', $uid)->exec();
 
 if (empty($result)) {//事務被取消
 echo '秒殺失敗';
 return false;
 }
 
 //搶券成功,將優惠券id和uid放入到隊列中,由一個單獨的進程隊列來消費隊列里的數據,向用戶推送搶到的優惠券
 $redis->lpush('couponorder', $couponid.'+'.$uid);
 
 $redis->close();
 return true;
}
 
$couponid = 11211;
$uid = mt_rand(1, 100);
seckill($couponid, $uid);

首先,我模擬設置優惠券id為11211的優惠券庫存為10個。

PHP+Redis事務解決高并發下商品超賣問題(推薦)

然后,我們使用ab工具來模擬1000次請求,50并發量來測試

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

然后我們通過redis desktop manager來查看一些redis的結果

couponorder隊列里已經有了10個用戶的信息了

PHP+Redis事務解決高并發下商品超賣問題(推薦)

并且優惠券的剩余數量也是0了,不再是負數了

PHP+Redis事務解決高并發下商品超賣問題(推薦)

同時,用戶搶券集合里也保存了10個用戶的uid信息。

PHP+Redis事務解決高并發下商品超賣問題(推薦)

上面這串代碼解決了兩個問題:

  • 解決了瞬時的大量查詢到數據庫上給數據庫造成很大壓力的問題,流量都被攔截在了redis緩存層
  • 解決了優惠券被超庫存搶購的問題

但是,這段代碼也存在一定的問題:

  1. 沒有使用redis連接池,頻繁創建新的redis有一定的性能影響
  2. 由于使用了事務,每一次并發請求中只會有一個用戶搶券成功,該并發請求中的其它用戶都會失敗,只能等第二次并發
  3. 同樣還是事務導致的庫存遺留問題,如果有10個商品,1000次請求每次200并發量,5次并發請求就完成了1000次請求,但是只會有5個用戶成功搶到,如果沒有后續的請求,會導致庫存還有5份存量

提示:在消費隊列里,如果優惠券發放失敗,一定要立即記錄并短信通知運營管理人員,看看是否能重發或者通過后臺手動定向推送給用戶。

所以,后續我又使用了lua腳本和redis配合一起來解決了這個問題。具體代碼,我會后續整理處理補充完整。

總結

到此這篇關于php+redis事務解決高并發下商品超賣問題的文章就介紹到這了,更多相關php redis 解決高并發下商品超賣內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://www.cnblogs.com/itbsl/archive/2020/08/02/13418176.html

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 日本黄a三级三级三级 | 国产成人精品综合在线观看 | 男gaygays免费网站多人 | 男男互操文 | 色综合久久综合网欧美综合网 | 亚洲国产欧美在线人网站 | 免费国产一级观看完整版 | 久久久久久久久女黄9999 | 亚洲咪咪| 国产精品1 | 亚洲国产情侣偷自在线二页 | 手机在线观看网站免费视频 | 啊好痛嗯轻一点免费 | 黄色cc| 日韩毛片高清在线看 | 青草热久精品视频在线观看 | 精品国产国偷自产在线观看 | 成人国产第一区在线观看 | 俄罗斯年轻男同gay69 | 亚洲va欧美va国产综合久久 | 香蕉久草在线 | 精品视频手机在线观看免费 | 精品国产福利在线 | 国产成人在线小视频 | 美女的隐私无遮挡撒尿 | 亚洲第一免费播放区 | 色婷婷在线 | 久久精品亚洲国产AV涩情 | 国产高清露脸学生在线观看 | 外国xxx| nxgx国产| 亚洲免费网站在线观看 | 99视频在线看观免费 | 欧美视频一区二区三区在线观看 | 99精品偷自拍| 丝瓜视频在线观看污 | 日本四虎影视 | 高中生放荡日记高h娜娜 | bl双性小说 | 秋葵丝瓜茄子草莓榴莲樱桃 | 爽好紧别夹宝贝叫大声点护士 |