#查看插件列表
rabbitmq-plugins list
#如果未安裝,則下載
wget https://dl.bintray.com/rabbitmq/community-plugins/3.7.x/rabbitmq_delayed_message_exchange/rabbitmq_delayed_message_exchange-20171201-3.7.x.zip
#解壓
unzip rabbitmq_delayed_message_exchange-20171201-3.7.x.zip
#移動到rabbitmq plugins文件夾中,本機的rabbitmq是docker容器,plugins文件夾位於/plugins
mv rabbitmq_delayed_message_exchange-20171201-3.7.x.ez ./plugins
#啓用rabbitmq_delayed_message_exchange插件
rabbitmq-plugins enable rabbitmq_delayed_message_exchange
#查看插件啓用情況
rabbitmq-plugins list
重啓rabbitmq
2,php-rabbitmq(自行composer安裝)
<?php
public function initDelay($queue_name)
{
//獲取配置
$queue_config = $this->parseQueueConfig($queue_name);
$host = $queue_config['host'];
$port = $queue_config['port'];
$username = $queue_config['username'];
$password = $queue_config['password'];
//創建連接
$this->connection = new AMQPStreamConnection($host, $port, $username, $password);
$this->channel = $this->connection->channel();
$this->channel->exchange_declare(
$queue_name,
//exchange類型爲x-delayed-message
'x-delayed-message',
false,
true,
false,
false,
false,
//此處是重點,$argument必須使用new AMQPTable()生成
new AMQPTable([
"x-delayed-type" => 'direct'
])
);
//隊列聲明
$this->channel->queue_declare($queue_name, false, true, false, false);
//隊列與exchange綁定
$this->channel->queue_bind($queue_name, $queue_name, $queue_name);
}
//生成消息
private function createDelayMsg($data)
{
$this->msg = new AMQPMessage(
$data,
[
'delivery_mode' => AMQPMessage::DELIVERY_MODE_PERSISTENT,
//此處是重點,設置延時時間,單位是毫秒 1s=1000ms,實例延遲20s
'application_headers' => new AMQPTable([
'x-delay' => 20000,
])
]
);
return $this->msg;
}
//生產者發送消息,代碼中只需調用此方法發送消息即可
public function publishDelayMsg($queue_name, $msg_data)
{
$this->initDelay($queue_name);
$msg = $this->createDelayMsg($msg_data);
$this->channel->basic_publish($msg, $queue_name, $queue_name);
$this->channel->close();
$this->connection->close();
}
//消費者,代碼中調用消費
public function workerMsg($queue_name, $callback = null)
{
$this->init($queue_name);
$this->channel->basic_qos(null, 1, null);
$this->channel->basic_consume($queue_name, '', false, false, false, false, $callback);
while (count($this->channel->callbacks)) {
$this->channel->wait();
}
$this->channel->close();
$this->connection->close();
}
//常駐內存 消費實例
protected function execute(InputInterface $input, OutputInterface $output)
{
$queue = new QueueService();
$queue->workerMsg('order_check', function ($msg) {
$unique = md5(uniqid(time()));
try {
logger("[$unique]order check Queue Received[{$msg->body}] ");
$orderData = json_decode($msg->body, true);
$orderId = $orderData['id'];
$flag = array_get($orderData, 'flag');
$order = new OrderService();
list($code, $errMsg,) = $order->changeOrderStatus($orderId, $flag);
if ($code > 0) {
//意外錯誤重新分配
logger("[$unique]order check Queue Exception[{$code} {$errMsg}] ");
$msg->delivery_info['channel']->basic_reject($msg->delivery_info['delivery_tag'], false);
} else {
$msg->delivery_info['channel']->basic_ack($msg->delivery_info['delivery_tag']);
}
} catch (\Exception $e) {
//意外錯誤重新分配
logger("[$unique]order check Queue Exception[{$e->getCode()} {$e->getMessage()}] ");
$msg->delivery_info['channel']->basic_reject($msg->delivery_info['delivery_tag'], false);
}
});
}