基於Redis的MessageQueue隊列封裝

來源:互聯網
上載者:User

原創文章,轉載請註明出處:http://www.huyanping.cn/?p=275
作者:Jenner

Redis的鏈表List可以用來做鏈表,高並發的特性非常適合做分布式的並行訊息傳遞。

項目地址:https://github.com/huyanping/Zebra-PHP-Framework

左進右出

$redis->lPush($key, $value);$redis->rPop($key);

 以下程式已在生產環境中正式使用。

基於Redis的PHP訊息佇列封裝

<?php/** * Created by PhpStorm. * User: huyanping * Date: 14-8-19 * Time: 下午12:10 * * 基於Redis的訊息佇列封裝 */namespace Zebra\MessageQueue;class RedisMessageQueue implements IMessageQueue{    protected $redis_server;    protected $server;    protected $port;    /**     * @var 訊息佇列標誌     */    protected $key;    /**     * 構造隊列,建立redis連結     * @param $server_config     * @param $key     * @param bool $p_connect     */    public function __construct($server_config = array('IP' => '127.0.0.1', 'PORT' => '6379'), $key = 'redis_message_queue', $p_connect = false)    {        if (empty($key))            throw new \Exception('message queue key can not be empty');        $this->server = $server_config['IP'];        $this->port = $server_config['PORT'];        $this->key = $key;        $this->check_environment();        if ($p_connect) {            $this->pconnect();        } else {            $this->connect();        }    }    /**     * 解構函式,關閉redis連結,使用長串連時,最好主動調用關閉     */    public function __destruct()    {        $this->close();    }    /**     * 短串連     */    private function connect()    {        $this->redis_server = new \Redis();        $this->redis_server->connect($this->server, $this->port);    }    /**     * 長串連     */    public function pconnect()    {        $this->redis_server = new \Redis();        $this->redis_server->pconnect($this->server, $this->port);    }    /**     * 關閉連結     */    public function close()    {        $this->redis_server->close();    }    /**     * 向隊列插入一條資訊     * @param $message     * @return mixed     */    public function put($message)    {        return $this->redis_server->lPush($this->key, $message);    }    /**     * 向隊列中插入一串資訊     * @param $message     * @return mixed     */    public function puts(){        $params = func_get_args();        $message_array = array_merge(array($this->key), $params);        return call_user_func_array(array($this->redis_server, 'lPush'), $message_array);    }    /**     * 從隊列頂部擷取一條記錄     * @return mixed     */    public function get()    {        return $this->redis_server->lPop($this->key);    }    /**     * 選擇資料庫,可以用於區分不同隊列     * @param $database     */    public function select($database)    {        $this->redis_server->select($database);    }    /**     * 獲得隊列狀態,即目前隊列中的訊息數量     * @return mixed     */    public function size()    {        return $this->redis_server->lSize($this->key);    }    /**     * 擷取某一位置的值,不會刪除該位置的值     * @param $pos     * @return mixed     */    public function view($pos)    {        return $this->redis_server->lGet($this->key, $pos);    }    /**     * 檢查Redis擴充     * @throws Exception     */    protected function check_environment()    {        if (!\extension_loaded('redis')) {            throw new \Exception('Redis extension not loaded');        }    }}

如果需要一次寫入多個隊列,可以使用如下調用方式:

<?php$redis = new RedisMessageQueue();$redis->puts(1, 2, 3, 4);$redis->puts(5, 6, 7, 8, 9);

模仿HTTPSQS輸出結果的封裝如下,提供了寫入位置和讀取位置記錄的功能:

<?php/** * Created by PhpStorm. * User: huyanping * Date: 14-9-5 * Time: 下午2:16 * * 附加了隊列狀態資訊的RedisMessageQueue */namespace Zebra\MessageQueue;class RedisMessageQueueStatus extends RedisMessageQueue {    protected $record_status;    protected $put_position;    protected $get_position;    public function __construct(        $server_config = array('IP' => '127.0.0.1', 'PORT' => '6379'),        $key = 'redis_message_queue',        $p_connect = false,        $record_status=true    ){        parent::__construct($server_config, $key, $p_connect);        $this->record_status = $record_status;        $this->put_position = $this->key . '_put_position';        $this->get_position = $this->key . '_get_position';    }    public function get(){        if($queue = parent::get()){            $incr_result = $this->redis_server->incr($this->get_position);            if(!$incr_result) throw new \Exception('can not mark get position,please check the redis server');            return $queue;        }else{            return false;        }    }    public function put($message){        if(parent::put($message)){            $incr_result = $this->redis_server->incr($this->put_position);            if(!$incr_result) throw new \Exception('can not mark put position,please check the redis server');            return true;        }else{            return false;        }    }    public function puts_status(){        $message_array = func_get_args();        $result = call_user_func_array(array($this, 'puts'), $message_array);        if($result){            $this->redis_server->incrBy($this->put_position, count($message_array));            return true;        }        return false;    }    public function size(){        return $this->redis_server->lSize($this->key);    }    public function status(){        $status['put_position'] = ($put_position = $this->redis_server->get($this->put_position)) ? $put_position : 0;        $status['get_position'] = ($get_position = $this->redis_server->get($this->get_position)) ? $get_position : 0;        $status['unread_queue'] = $this->size();        $status['queue_name'] = $this->key;        $status['server'] = $this->server;        $status['port'] = $this->port;        return $status;    }    public function status_normal(){        $status = $this->status();        $message  = 'Redis Message Queue' . PHP_EOL;        $message .= '-------------------' . PHP_EOL;        $message .= 'Message queue name:' . $status['queue_name'] . PHP_EOL;        $message .= 'Put position of queue:' . $status['put_position'] . PHP_EOL;        $message .= 'Get position of queue:' . $status['get_position'] . PHP_EOL;        $message .= 'Number of unread queue:' . $status['unread_queue'] . PHP_EOL;        return $message;    }    public function status_json(){        return \json_encode($this->status());    }}

 

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.