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;
}
}
}