1. 程式人生 > >php+redis+TP處理併發

php+redis+TP處理併發

前兩天想自己研究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('購買成功。');
    }

就是這麼簡單,不僅高效,而且不會出現超賣情況,很實用的併發處理。