簡體   English   中英

如何使用PHP的RabbitMQ延遲消息隊列?

[英]How do I use the RabbitMQ delayed message queue from PHP?

我正在嘗試從PHP使用RabbitMQ的Delayed Message Queue ,但我的消息正在消失。

我用以下代碼聲明交換:

$this->channel->exchange_declare(
    'delay',
    'x-delayed-message',
    false,  /* passive, create if exchange doesn't exist */
    true,   /* durable, persist through server reboots */
    false,  /* autodelete */
    false,  /* internal */
    false,  /* nowait */
    ['x-delayed-type' => ['S', 'direct']]);

我用這段代碼綁定隊列:

$this->channel->queue_declare(
    $queueName,
    false,  /* Passive */
    true,   /* Durable */
    false,  /* Exclusive */
    false   /* Auto Delete */
);
$this->channel->queue_bind($queueName, "delay", $queueName);

我正在使用以下代碼發布消息:

$msg = new AMQPMessage(json_encode($msgData), [
    'delivery_mode' => 2,
    'x-delay' => 5000]);
$this->channel->basic_publish($msg, 'delay', $queueName);

但消息不會延遲; 它仍然立即交付。 我錯過了什么?

這里開始

消息創建應該是

require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Message\AMQPMessage;
use PhpAmqpLib\Wire\AMQPTable;

$msg = new AMQPMessage($data,
            array(
                'delivery_mode' => 2, # make message persistent
                'application_headers' => new AMQPTable([
                    'x-delay' => 5000
                ])
            )
        );

答案是針對那些需要延遲消息但又不想深入了解細節的人。 你只需要一些東西就能讓它發揮作用:

安裝amqp interop兼容傳輸,例如enqueue/amqp-bunnyenqueue/amqp-tools

composer require enqueue/amqp-bunny enqueue/amqp-tools

創建amqp上下文,添加延遲策略並發送延遲消息:

<?php
use Enqueue\AmqpTools\RabbitMqDelayPluginDelayStrategy;
use Enqueue\AmqpBunny\AmqpConnectionFactory;

$context = (new AmqpConnectionFactory('amqp://'))->createContext();
$context->setDelayStrategy(new RabbitMqDelayPluginDelayStrategy())

$queue = $context->createQueue('foo');
$context->declareQueue($queue);

$message = $context->createMessage('Hello world!');

$context->createProducer()
    ->setDeliveryDelay(5000) // 5 sec
    ->send($queue, $message)
;

順便說一句,這不是唯一可用的策略。 有一個基於RabbitMQ死信隊列+ ttl。 它可以以相同的方式使用。

您需要一個路由密鑰才能從交換機發布到相關隊列。

發布到內置直接交換的原因是因為此交換是使用路由密鑰作為目標隊列名稱的特殊情況。

對於您創建的所有交換和隊列,您需要使用路由密鑰在交換和隊列之間創建綁定。 然后使用該路由密鑰而不是目標隊列名稱發布消息。

我不知道創建綁定的PHP代碼...但它通常看起來像這樣:

channel.bind(exhange_name, queue_name, routing_key)

然后在你發布消息時:

$this->channel->basic_publish($msg, 'delay', $routing_key);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM