單例設計 實現 RabbitMQ封裝類

1 入口

// 需要推送的數據,扔進工廠,開始進入推送邏輯
Goods::shareGoodsPush([
    'sku'           => $insertData['sku'] ?? '',
    'name'          => $insertData['name'] ?? '',
    'price'         => $insertData['price'] ?? 0,
    'teacher_ids'   => $insertData['teacher_ids'] ?? '',
    'description'   => $insertData['synopsis'] ?? '',
    'status'        => 1, // 數據庫默認爲 1
    'sales_volume'  => $insertData['sales_volume'] ?? 0,
    'id'            => $goods->id ?? 0,
    'cover_bak_img' => $insertData['cover_bak_img'] ?: $insertData['cover_img'],
    'sku_type'      => $insertData['sku_type'] ?? 0,
    'end_time'      => $insertData['end_time'] ?? '',
    'is_hidden'     => $insertData['is_hidden'] ?? 1
]);

2 工廠 推送MQ邏輯

/***
 * 工廠方法
 * @param $goods_data
 * @author twj
 * @return bool
 */
public static function shareGoodsPush($goods_data)
{
    try {
        $host       = env('APP_DEBUG')
                        ? env('MQ_MPRE_GOOD_PUSH_HOST_test')  // 測試
                        : env('MQ_MPRE_GOOD_PUSH_HOST'); // 正式

        $port       = env('MQ_MPRE_GOOD_PUSH_PORT');
        $user       = env('MQ_MPRE_GOOD_PUSH_USER');
        $vhost      = env('MQ_MPRE_GOOD_PUSH_VHOST');
        $password   = env('MQ_MPRE_GOOD_PUSH_PASSWORD');

        $push_data = self::addAndEditGood($goods_data);// 過濾消息數據體

        $ins = RabbitMqService::getIns();
        $ins->initQueue('more_good_push', 'more.good.push', 'direct', 'm_good_share')// 初始化參數
            ->initAMQPStreamConnection( $host, $port, $user, $password, $vhost )// 創建連接
            ->initChannel() // 創建管道
            ->exchangeDeclare()// 創建交換機
            ->queueDeclare()// 創建隊列
            ->amqPMessage( $push_data )// 準備消息體
            ->queueBind()// 隊列和交換機通過severity綁定,即routing key
            ->basicPublish()// 消息推送到MQ
            ->close(); // 關閉連接

        return true;

    } catch (\Exception $e) {
        Log::info(
            '拋異常位置:class:GoodsController.update 異常位置:' . $e->getFile() .
            '; 異常行:' . $e->getLine() .
            '; 異常內容:' . $e->getMessage() .
            '; 異常數據:' . isset($push_data) && $push_data ? json_encode($push_data) : '';
        );
        return false;
    }
}

 

3 單例設計模式封裝類

<?php

namespace App\Service\RabbitMQ;

use PhpAmqpLib\Connection\AMQPStreamConnection;
use PhpAmqpLib\Message\AMQPMessage;

/***
 * 操作RabbitMQ類 目前暫不支持不使用交換機的情況
 * Class RabbitMqService
 * @package App\Service\RabbitMQ
 * @author twj
 */
class RabbitMqService
{
    /**
     * 當前實例
     * @var null
     */
    protected static $ins = null;
    /***
     * MQ連接
     * @var null
     */
    private $amqPStreamConnection = null;
    /***
     * 管道
     * @var null
     */
    private $channel = null;
    /***
     * 待推送消息體
     * @var null
     */
    private $msg = null;
    /***
     * Routing key
     * @var string
     */
    private $severity = '';
    /***
     * 隊列名稱
     * @var string
     */
    private $queue_name = '';
    /***
     * 交換機名字
     * @var string
     */
    private $exchange = '';
    /***
     * 交換機類型
     * @var string
     */
    private $exchange_type = '';

    /***
     * RabbitMqService constructor.
     * @author twj
     */
    final protected function __construct(){}

    /***
     * Prohibit cloning
     * @author twj
     */
    final protected function __clone(){}

    /***
     * 單例設計模式
     * @return RabbitMqService
     * @author twj
     */
    public static function getIns()
    {
        if (self::$ins === null) {
            self::$ins = new self();
        }
        return self::$ins;
    }

    /***
     * 初始化隊列和交換機相關參數
     * @param string $severity 綁定健,如果direct直連交換機必須要severity
     * @param string $queue_name 隊列名字
     * @param string $exchange 交換機名字
     * @param string $exchange_type 交換機類型
     * @return RabbitMqService
     * @author twj
     */
    public function initQueue($queue_name, $exchange, $exchange_type = 'direct', $severity = '')
    {
        $this->queue_name       = $queue_name;
        $this->exchange         = $exchange;
        $this->exchange_type    = $exchange_type;
        $this->severity         = $severity;
        return self::getIns();
    }

    /***
     * 連接rabbitMQ
     * @param $host
     * @param $port
     * @param $user
     * @param $password
     * @param string $vhost
     * @return RabbitMqService
     * @author twj
     */
    public function initAMQPStreamConnection($host, $port, $user, $password, $vhost = '/')
    {
        $this->amqPStreamConnection = new AMQPStreamConnection(
            $host,
            $port,
            $user,
            $password,
            $vhost
        );
        return self::getIns();
    }

    /***
     * 連接管道
     * @param null $channel_id 管道ID
     * @return RabbitMqService
     * @author twj
     */
    public function initChannel($channel_id = null)
    {
        $this->channel = $this->amqPStreamConnection->channel($channel_id);
        return self::getIns();
    }

    /***
     * 創建交換機
     * @param string exchange 交換機名字
     * @param string exchange_type 交換器類型,常見的如fanout、direct、topic、headers四種
     * @param bool $passive 設置此爲true即可如果交換機不存在,則會拋出一個錯誤的異常.如果存在則返回NULL
     * @param bool $durable 設置是否持久化。設置true表示持久化
     * @param bool $auto_delete 設置true表示自動刪除
     * @return RabbitMqService
     * @author twj
     */
    public function exchangeDeclare($passive = false, $durable = true, $auto_delete = false)
    {
        $this->channel->exchange_declare(
            $this->exchange,
            $this->exchange_type,
            $passive,
            $durable,
            $auto_delete
        );
        return self::getIns();
    }

    /***
     * 創建隊列
     * @param bool $passive 一般用於判斷該隊列是否存在
     * @param bool $durable 設置true表示持久化
     * @param bool $exclusive 設置是否排他
     * @param bool $auto_delete 設置是否自動刪除
     * @return RabbitMqService
     * @author twj
     */
    public function queueDeclare($passive = false, $durable = true, $exclusive = false, $auto_delete = false)
    {
        $this->channel->queue_declare(
            $this->queue_name, // 隊列名字
            $passive,
            $durable,
            $exclusive,
            $auto_delete
        );
        return self::getIns();
    }

    /***
     * 準備消息體
     * @param array $json_push_data
     * @return RabbitMqService
     * @author twj
     */
    public function amqPMessage($json_push_data)
    {
        $msg = new AMQPMessage(
            json_encode( $json_push_data ),
            [
                'content_type' => 'application/json',
                'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT // 消息持久化
            ]
        );
        $this->msg = $msg;
        return self::getIns();
    }

    /***
     * 綁定參數  隊列和交換機 綁定
     * @return RabbitMqService
     * @author twj
     */
    public function queueBind()
    {
        $this->channel->queue_bind($this->queue_name, $this->exchange, $this->severity);
        return self::getIns();
    }

    /***
     * 發送消息到對應的交換機 -> 交換機再通過severity -> 分配到對應的隊列
     * @return RabbitMqService
     * @author twj
     */
    public function basicPublish()
    {
        $this->channel->basic_publish(
            $this->msg,
            $this->exchange,// 交換機
            $this->severity // 隊列和交換機綁定的參數
        );
        return self::getIns();
    }

    /***
     * close MQ
     * @author twj
     */
    public function close()
    {
        $this->channel->close();
        $this->amqPStreamConnection->close();
    }

    /***
     * 程序報錯 終止單例執行
     * @return null exception error
     * @author twj
     */
    public function exception($code = 200)
    {
        if ($code != 200) {
            return null;
        }
    }

}

 

 

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