一、PHP消息隊列實現及應用 二、消息隊列的優缺點 三、消息隊列的配置和準備工作 案例如下: 下麵是隊列表欄位及屬性 四、Mysql訂單隊列 1、接受訂單,並寫入數據 order.php 2、隊列系統處理隊列中的訂單併進行標識goods.php 3、定時任務。每分鐘執行一次goods.sh 要會sh ...
一、PHP消息隊列實現及應用
二、消息隊列的優缺點
三、消息隊列的配置和準備工作
案例如下:
下麵是隊列表欄位及屬性
四、Mysql訂單隊列
1、接受訂單,並寫入數據 order.php
<?php //這個文件是用來接受用戶的訂單信息並寫入隊列的一個文件 //引入資料庫鏈接類 include '../include/db.php'; //當接收到用戶手機號不為空的時候 if(!empty($_GET['mobile'])){ //這裡首先是訂單中心的處理流程 //因為訂單系統是個單獨的流程 這裡需要處理 //...... 這裡不單獨寫了 //把用戶提交的數據進行過濾,防止sql註入 //直接假設個訂單號 $order_id = rand(10000,99999); //生成訂單信息 $insert_data = array( 'order_id'=>$order_id, 'mobile'=>$_GET['mobile'], 'created_at'=>date('Y-m-d H:i:s',time()), 'status'=>0,//0未處理 1已處理2處理中 ); //把訂單信息存入到隊列表中 $db = DB::getIntance();//此處是操作資料庫,註意不同的框架有相應的內置的操作方法 $res = $db->insert('order_queue',$insert_data);//insert($table,$data) if($res){ echo '插入成功'; }else{ echo '插入失敗'; } }
2、隊列系統處理隊列中的訂單併進行標識goods.php
<?php //這個文件主要是配送系統處理隊列中的訂單併進行標記的一個文件 //載入資料庫操作類 include '../include/db.php'; //初始化 $db = DB::getIntance(); //1:先把要處理的記錄更新為等待處理(此處要鎖定訂單,防止處理未完成便被取用) $waiting = array(‘status’=>0);//等待處理的數據 $lock = array(‘status’=>2);//鎖定的數據 $res_lock = $db->update('order_queue',$lock,$waiting,2);//update($table,$data,$where,$limit=0) //2:選擇出剛剛更新的數據,然後進行配送系統的處理 if($res_lock){ //選擇出要處理的訂單的內容 $res = $db->selectAll('order_queue',$lock);// //然後由配貨系統進行配貨處理 //......//此處是配貨系統 //3:把處理過的程式更新為已完成 $success = array( 'status'=>1,//已完成 'updated_at'=>date('Y-m-d H:i:s',time()), ); $res_last = $db->update('order_queue',$success,$lock); if($res_last){ echo 'Success'.$res_last; }else{ echo 'Fail'.$res_last; } }else{ echo 'ALL Finished'; }
3、定時任務。每分鐘執行一次goods.sh 要會shell基礎
#!/bin/bash date "+%G-%m-%d %H:%M:S" cd /home/html/ssggw/queue_mysql/ php goods.php
4、在伺服器部署下定時任務crontab -e
為了方便看結果,把定時任務結果輸出到日誌文件中,設定為標準輸出,命令如下
執行命令保存文件:wq
新建日誌文件命令
touch /home/html/ssggw/log.log
監控日誌文件
資料庫中已經成功兩條數據
資料庫中已經成功四條數據
解耦案例結束
五、Redis
六、Redis隊列實現秒殺
1、創建數據表 redis_queue
2、接受用戶請求的程式user.php
<?php //先載入redis組件 $redis = new Redis(); $redis->connect('127.0.0.1',6379); $redis_name = "miaosha"; //接受用戶id $uid = $_GET['uid']; //獲取下redis裡面已有的數量 $num = 10;//秒殺前10個 //如果當天人數少於10的時候,則加入這個隊列 if($redis->lLen($redis_name)<10){ $redis->rFush($redis_name,$uid.'%'.microtime());//將用戶uid(連接一個微妙)加入$fredis_name這個隊列的尾部 echo "秒殺成功"; }else{ //如果當天人數已經達到了10個人,則返回秒殺已完成 echo "秒殺已結束"; } //關掉redis鏈接 $redis->close();
3、處理程式,即報數據寫入mysql對應數據表savetodb.php
<?php //引入操作資料庫類 include '../include/db.php'; //載入redis組件 $redis = new Redis(); $redis->connect('127.0.0.1',6379); $redis_name = "miaosha"; $db = DB::getlntance(); //死迴圈 while(1){ //從隊列最左側取出一個值來 $user = $redis->IPop($redis_name); //然後判斷這個值是否存在 if(!$user || $user =='nil'){ //減少伺服器壓力 每1秒執行一次 真正的秒殺時間會很短,不用設置 sleep(1); //跳出迴圈 continue; } //切割出時間,uid $user_arr = explode('%',$user); //定義一個數組 $insert_data = array( 'uid'=>$user_arr[0], 'time_stamp'=>$user_arr[1], ); //保存到資料庫中 $res = $db->insert('redis_queue',$insert_data); //資料庫插入失敗的時候的回滾機制 if(!$res){ $redis->rPush($redis_name,$user); } } //釋放一下redis $redis->close();
測試
訪問user.php文件url
結果
資料庫表情況