php+redis+TP處理併發
阿新 • • 發佈:2019-02-15
前兩天想自己研究PHP的併發問題,看到很多人都說用redis的佇列處理併發很好,所以自己也去研究了一下,下面用實際專案記錄一下自己的成果。
基本思路是所有操作用過redis的佇列和集合處理併發
1.使用者搶購佇列(List),user_list
2.商品佇列(List),goods_list
3.訂單資訊(Hash集合),order_info
4.購買成功使用者(Set集合),bought_list
PS:1和2用來控制併發,佇列的rPop是具有原子性的,即使處理併發,也是一個個處理,不會出現重複和超賣的情況。
3則是用來暫時存放訂單資訊,之後再入庫。
4是為了防止使用者重複購買做的(Set的特性是不能重複)。
併發模擬則是在Linux的webbench做的。
經過試驗發現,併發1000條的搶購,直接操作資料庫要12秒,使用redis只要6秒,速度快了整整一倍!
下面貼原始碼
商品入貨1000個:
public function ruhuo(){ $redis = new \redis(); $redis->connect('127.0.0.1', 6379); for($i = 1;$i<=1000;$i++) $redis->lpush('goods_list',$i); echo '進貨成功'; }
秒殺介面:
public function redis_qianghuo(){ $redis = new \redis(); $redis->connect('127.0.0.1', 6379); //查詢庫存 if($redis->lLen('goods_list') == 0) $this->ajaxReturn('商品已售完...'); $uid = $_SERVER['REMOTE_PORT']; //查詢是否購買過 if($redis->sIsMember('bought_list',$uid)) $this->ajaxReturn('你已經購買過了!'); $goods_id = $redis->rpop('goods_list'); $redis->sAdd('bought_list',$uid); $value = array( 'uid' => $uid, 'goods_id' => $goods_id, 'time' => time(), ); $redis->hSet('order_info',$uid,json_encode($value)); $this->ajaxReturn('購買成功。'); }
就是這麼簡單,不僅高效,而且不會出現超賣情況,很實用的併發處理。