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