本文轉自: https://blog.csdn.net/weixin_39278982/article/details/81216416
消息隊列的應用場景例如:秒殺、搶單功能。
下面寫個Demo簡單實現一下秒殺,也就是搶購。
首先創建一個lpush.html文件,代碼如下:
<!DOCTYPE html>
<html>
<head>
<title>TODO supply a title</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="jquery-3.2.1.min.js" ></script>
<script>
function push(uid){
$('#msg'+uid).html('請耐心等待.......');
$.get('lpush.php',{"uid":uid},function (data){
if(data == 1 ){
$('#msg'+uid).html('搶購成功!!');
}else{
$('#msg'+uid).html('搶購失敗!!');
}
});
}
</script>
</head>
<body>
<span id="msg5"></span><br>
<input type="button" value="搶購5" οnclick="push(5)"><br>
<span id="msg15"></span><br>
<input type="button" value="搶購15" οnclick="push(15)"><br>
<span id="msg25"></span><br>
<input type="button" value="搶購25" οnclick="push(25)"><br>
<span id="msg35"></span><br>
<input type="button" value="搶購35" οnclick="push(35)"><br>
<span id="msg45"></span><br>
<input type="button" value="搶購45" οnclick="push(45)"><br>
<span id="msg55"></span><br>
<input type="button" value="搶購55" οnclick="push(55)"><br>
</body>
</html>
然后在創建一個lpush.php文件用來處理數據,這個文件里頭的內容呢就是執行入隊操作,代碼如下:
<?php
//實例化redis對象
$redis = new redis();
//連接redis,第一個參數是redis服務的IP127.0.0.1是自己的,6379是端口號
$redis->connect('127.0.0.1', 6379);
//接收ajax傳來的值,請看lpush.html
$uid = $_GET['uid'];
//入隊列
$redis->lpush('tv', $uid);
//寫一個死循環用來判斷結果
while (true) {
//守護進程是否將所有訂單處理完畢
if ($redis->scard('tvuser') == 5) {
//判斷當前用戶是否有對應的訂單
if ($redis->sismember('tvuser' , $uid)) {
$flag = 1;
} else {
$flag = 0;
}
//返回給頁面
echo $flag;
//滿足條件后停止循環
break;
}
}
?>
最后在創建一個守護進程的文件pop.php,這個文件里頭的主要內容就是去隊列里頭的值並且返回人數是否已夠,代碼如下:
<?php
//實例化redis對象
$redis = new redis();
//連接redis,第一個參數是redis服務的IP127.0.0.1是自己的,6379是端口號
$redis->connect('127.0.0.1', 6379);
//定義一個變量用來存儲循環次數
$num = 0;
//循環取值
while (true) {
//每隔一秒取一次
sleep(1);
//redis取值
$uid = $redis->rpop('tv');
//判斷取出來的UID又沒有值
if ($uid > 0) {
//有值
//create order 生成用戶對應的訂單
echo 'order created for user ' . $uid . "\r\n";
$redis->sadd('tvuser' , $uid); //搶購成功的用戶id
//如果有值的話num會++
$num++;
} else {
//無值
//insert log
echo 'no uid ' . "\r\n";
}
//如果num值大於等於5那么循環終止,循環次數是看秒殺多少件商品來變的,這里的話我就定義了5次
if ($num >= 5) {
break;
}
}
?>
我們在執行守護進程之前可以先把redis里的數據清空一下,以免擾亂程序執行結果,命令如下:

效果就是這個樣子的,在秒殺開始之前要先啟動守護進程,命令效果如下:

然后守護進程啟動之后,前台就可以來進行秒殺了。瀏覽器上訪問你的lpush.html,由於我們后台設定的商品數為5,那么只能五個用戶搶購成功,第6個用戶就會提示失敗,如下圖:

