PHP快速使用RabbitMQ實現項目中部分業務的解耦

前言:

        上次介紹了RabbitMQ在windows下的安裝,以及PHP的AMQP擴展的添加。這裏將本地測試的代碼放到了服務,所以也就是在Linux上再裝一遍。但是這裏就省掉直接進入使用。主要是RabbitMQ安裝完畢後,管控臺的使用以及在PHP中如何調用其接口實現消息的生產和消費。

 

步驟:

1. Linux安裝完rabbitMQ後,沒有配置文件,需要去github(https://github.com/rabbitmq/rabbitmq-server/tree/master/docs)上將rabbitmq.conf.example複製下載下來改爲rabbitmq.conf。

2. 可以修改默認Vhost和管理員默認賬號密碼,最重要的是要將管理員開放給所有IP都可以登錄(默認是隻能是本地可以登錄),修改方式如下。

3. 進入到管控臺後,先創建vhost,點擊admin,側欄框點擊Virtual Hosts。

4. 添加Exchanges,先選擇對應的Vhost

5. 添加隊列,選擇Queues,選擇對應的Vhost

6. 隊列添加完畢後選擇其中一個添加的名稱進入。

7. 綁定之前的Exchanges中其中一個,輸入exchanges名字和自定義一個路由Key。

 

8. 成功後就可以通過PHP代碼生產消息到該虛擬機,然後經過交換機路由到該隊列中。

<?php


namespace rabbitmq;


class Amq
{
    /**
     * @var object 對象實例
     */
    protected static $instance;

    protected $exchange='router_visit';  // 交換機(需要在隊列中綁定)
    protected $queue ='visit_log';       // 隊列
    protected $route ='router_visit';    // 路由key(需要在隊列中綁定)
    protected $consumer_tag='consumer';
    protected $config = [
        'host' => '146.53.206.264',
        'port' => 5672,
        'login' => 'guest',		//guest
        'password' => 'guest',	//Na18gR@9tf
        'vhost' => 'log',
        'amqp_debug' => true
    ];
    protected $exchange_index = 0;
    protected $exchange_type = [
        'direct',
        'fanout',
        'topic',
        'headers'
    ];

    /**
     * @note 實例化
     * @author: beiqiaosu
     * @since: 2019/11/13 16:10
     */
    public static function getInstance()
    {
        if (!(self::$instance instanceof self)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

	
    /**
     * @Notes: 消息生產
     */
    public function publisher($message,$config=[]) {
        //如果有配置就用新配置
        $this->config ['vhost'] = $config['vhost']?? $this->config ['vhost'];
        $this->exchange = $config['exchange']?? $this->exchange;
        $this->queue = $config['queue']?? $this->queue;

        $this->consumer_tag = $config['consumer_tag']?? $this->consumer_tag;
        $this->route = $config['route']?? $this->route;
        $this->exchange_index = $config['exchange_index']?? $this->exchange_index;

        $cnn = new \AMQPConnection($this->config);
        if (!$cnn->connect()) {
            echo "Cannot connect to the broker";
            exit();
        }

        $channel = new \AMQPChannel($cnn);
        $ex = new \AMQPExchange($channel);
        $ex->setName($this->exchange);

        $ex->setType(AMQP_EX_TYPE_DIRECT); //direct類型

        $ex->setFlags(AMQP_DURABLE); //持久化
        $ex->declareExchange();
        return "Send Message:".$ex->publish($message, $this->route, AMQP_NOPARAM, array('delivery_mode' => 2))."\n";
    }


    /**
     * @note 消費
     * @author: tata
     * @since: 2019/11/13 16:10
     */
    public function consumer() {

        $exchange='router_visit';       //交換機
        $queue ='visit_log';         //隊列
        $route ='router_visit';        //路由

        //連接broker
        $cnn = new \AMQPConnection($this->config);
        if (!$cnn->connect()) {
            echo "Cannot connect to the broker";
            exit();
        }
        $channel = new \AMQPChannel($cnn);
        $ex = new \AMQPExchange($channel);
        //設置交換機名稱
        $ex->setName($exchange);
        //設置交換機類型
        //AMQP_EX_TYPE_DIRECT:直連交換機
        //AMQP_EX_TYPE_FANOUT:扇形交換機
        //AMQP_EX_TYPE_HEADERS:頭交換機
        //AMQP_EX_TYPE_TOPIC:主題交換機
        $ex->setType(AMQP_EX_TYPE_DIRECT);
        //設置交換機持久
        $ex->setFlags(AMQP_DURABLE);
        //聲明交換機
        $ex->declareExchange();
        //創建一個消息隊列
        $q = new \AMQPQueue($channel);
        //設置隊列名稱
        $q->setName($queue);
        //設置隊列持久
        $q->setFlags(AMQP_DURABLE);
        //聲明消息隊列
        //$q->declareQueue();
        //交換機和隊列通過$route進行綁定
        $q->bind($exchange, $route);

        $ret = $q->consume(function($envelope, $queue) {

            // 取出消息主題轉爲數組
//            $origin_data = json_decode($envelope->getBody(),true);
//            dump($envelope->getBody());die;

            /**對消息主題執行業務**/
            $res = true;
            /**對消息主題執行業務**/

            // 業務處理完畢發送給MQ消費掉該消息
            if ($res) $queue->ack($envelope->getDeliveryTag()); //手動發送ACK應答
        });

        dump($ret);die;

        $cnn->disconnect();
    }

}

9. 每執行一次生產或消費代碼,可以在Queue中的統計或圖表中看到,測試代碼是否成功。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章