簡體   English   中英

Rabbit-Mq被拒絕后不會路由到死信隊列

[英]Rabbit-Mq not routing to dead letter queue after being rejected

我正在玩Rabbit-Mq,我正在嘗試實現一個“死信”隊列,一個失敗消息的隊列。 我一直在閱讀兔子文檔: https//www.rabbitmq.com/dlx.html

並提出了這個例子:

internal class Program
{
    private const string WorkerExchange = "work.exchange";
    private const string RetryExchange = "retry.exchange";
    public const string WorkerQueue = "work.queue";
    private const string RetryQueue = "retry.queue";

    static void Main(string[] args)
    {
        var factory = new ConnectionFactory { HostName = "localhost" };

        using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.ExchangeDeclare(WorkerExchange, "direct");
                channel.QueueDeclare
                (
                    WorkerQueue, true, false, false,
                    new Dictionary<string, object>
                    {
                        {"x-dead-letter-exchange", RetryExchange},

                        // I have tried with and without this next key
                        {"x-dead-letter-routing-key", RetryQueue}
                    }
                );
                channel.QueueBind(WorkerQueue, WorkerExchange, string.Empty, null);

                channel.ExchangeDeclare(RetryExchange, "direct");
                channel.QueueDeclare
                (
                    RetryQueue, true, false, false,
                    new Dictionary<string, object> {
                        { "x-dead-letter-exchange", WorkerExchange },
                        { "x-message-ttl", 30000 },
                    }
                );
                channel.QueueBind(RetryQueue, RetryExchange, string.Empty, null);

                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);

                    Thread.Sleep(1000);
                    Console.WriteLine("Rejected message");

                    // also tried  channel.BasicNack(ea.DeliveryTag, false, false);
                    channel.BasicReject(ea.DeliveryTag, false);
                };

                channel.BasicConsume(WorkerQueue, false, consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }
    }
}

發布到工作隊列時的隊列映像: rabbit-mq worker queue stats

重試隊列的圖像: rabbit-mq重試統計數據

我覺得好像我錯過了一些小細節,但似乎無法找到它們是什么。

提前致謝

您應該將死信交換定義為fanout

我們去: channel.ExchangeDeclare(RetryExchange, "fanout");

如果您的死信交換設置為DIRECT,則必須指定死信路由密鑰。 如果您只是希望所有NACKed消息進入死信桶以供以后調查(就像我一樣)那么您的死信交換應設置為FANOUT。

請查看此信息以獲取更多信息

事實證明,如果死信交換是direct交換,則隊列參數需要x-dead-letter-routing-key 上面(在問題中)我在字典中使用這個鍵來嘗試路由我的消息但是我沒做的是添加一個到我的綁定的路由,這里是一個有效的代碼的更新版本:

internal class Program
{
    private const string WorkerExchange = "work.exchange";
    private const string RetryExchange = "retry.exchange";
    public const string WorkerQueue = "work.queue";
    private const string RetryQueue = "retry.queue";

    static void Main(string[] args)
    {
        var factory = new ConnectionFactory { HostName = "localhost" };

        using (var connection = factory.CreateConnection())
        {
            using (var channel = connection.CreateModel())
            {
                channel.ExchangeDeclare(WorkerExchange, "direct");
                channel.QueueDeclare
                (
                    WorkerQueue, true, false, false,
                    new Dictionary<string, object>
                    {
                        {"x-dead-letter-exchange", RetryExchange},
                        {"x-dead-letter-routing-key", RetryQueue}
                    }
                );
                channel.QueueBind(WorkerQueue, WorkerExchange, WorkerQueue, null);

                channel.ExchangeDeclare(RetryExchange, "direct");
                channel.QueueDeclare
                (
                    RetryQueue, true, false, false,
                    new Dictionary<string, object>
                    {
                        {"x-dead-letter-exchange", WorkerExchange},
                        {"x-dead-letter-routing-key", WorkerQueue},
                        {"x-message-ttl", 30000},
                    }
                );
                channel.QueueBind(RetryQueue, RetryExchange, RetryQueue, null);

                var consumer = new EventingBasicConsumer(channel);
                consumer.Received += (model, ea) =>
                {
                    var body = ea.Body;
                    var message = Encoding.UTF8.GetString(body);
                    Console.WriteLine(" [x] Received {0}", message);

                    Thread.Sleep(1000);
                    Console.WriteLine("Rejected message");
                    channel.BasicNack(ea.DeliveryTag, false, false);
                };

                channel.BasicConsume(WorkerQueue, false, consumer);

                Console.WriteLine(" Press [enter] to exit.");
                Console.ReadLine();
            }
        }
    }

不同之處在於調用channel.QueueBind(WorkerQueue, WorkerExchange, WorkerQueue, null); 現在提供的路由密鑰與queuename相同,所以當消息“dead-letters”時,它會通過這個密鑰路由到交換機

暫無
暫無

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

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