rabbitmq的死信隊列

DLX, Dead-Letter-Exchange。利用DLX, 當消息在一個隊列中變成死信(dead message)以後,它能被從新publish到另外一個Exchange,這個Exchange就是DLX。消息變成死信一貫有一下幾種狀況:html

DLX也是一個正常的Exchange,和通常的Exchange沒有區別,它能在任何的隊列上被指定,實際上就是設置某個隊列的屬性,當這個隊列中有死信時,RabbitMQ就會自動的將這個消息從新發布到設置的Exchange上去,進而被路由到另外一個隊列,能夠監聽這個隊列中消息作相應的處理,這個特性能夠彌補RabbitMQ 3.0之前支持的immediate參數(能夠參考RabbitMQ之mandatory和immediate)的功能。app

核心代碼實現:經過在queueDeclare方法中加入「x-dead-letter-exchange」實現。spa

channel.exchangeDeclare("some.exchange.name", "direct");

Map<String, Object> args = new HashMap<String, Object>();
args.put("x-dead-letter-exchange", "some.exchange.name");
channel.queueDeclare("myqueue", false, false, false, args);

你也能夠爲這個DLX指定routing key,若是沒有特殊指定,則使用原隊列的routing key.net

args.put("x-dead-letter-routing-key", "some-routing-key");
  •  

還能夠使用policy來配置:code

rabbitmqctl set_policy DLX ".*" '{"dead-letter-exchange":"my-dlx"}' --apply-to queues
  •  

修改RabbitMQ之TTL(Time-To-Live 過時時間)中的例子:htm

public static void createQueue(){
    try {
        ConnectionFactory factory = new ConnectionFactory();
        factory.setHost(ip);
        factory.setPort(port);
        factory.setUsername(username);
        factory.setPassword(password);

        Connection connection = factory.newConnection();
        Channel channel = connection.createChannel();

        Map<String, Object>  argss = new HashMap<String, Object>();
        argss.put("vhost", "/");
        argss.put("username","root");
        argss.put("password", "root");
        argss.put("x-message-ttl",6000);
        argss.put("x-dead-letter-exchange","exchange.dlx.test");
 argss.put("x-dead-letter-routing-key","queue.dlx.test");
        channel.queueDeclare("queue.dlx.test", durable, exclusive, autoDelete, argss);
    } catch (IOException e) {
        e.printStackTrace();
    } catch (TimeoutException e) {
        e.printStackTrace();
    }
}

經過RabbitMQ的管理界面能夠看到: 
這裏寫圖片描述 
queue.dlx.test這個queue中有個「DLX」和「DLK」的標記. DLX關聯的是exchangeName, DLK關聯的是routingKey.blog

詳細說明: 
在RabbitMQ中有兩個exchange: exchange.dlx.self和exchange.dlx.test,兩個queue:queue.dlx.test和%DLX%queue.dlx.test 
exchange.dlx.self是正常狀況下,生產者發送消息到此exchange中,綁定關係如圖: 
這裏寫圖片描述 
exchang.dlx.test是產生死信以後,原queue[queue.dlx.test]的死信發送到此exchange中,綁定關係如圖: 
這裏寫圖片描述rabbitmq

數據首先發送到 exchange[exchange.dlx.self],根據routingkey[dlx]路由到queue.dlx.test,若是正常狀況下,消費者能夠消費queue.dlx.test的內容。可是若是queue.dlx.test中有消息變成了dead message即死信了,那麼這個死信則會經過exchangeName=exchange.dlx.test, routingKey=」queue.dlx.test」路由到死信隊列%DLX%queue.dlx.test中,若是要消費這個dead message, 此時消費者必須消費%DLX%queue.dlx.test中的內容而不是queue.dlx.test中的內容。隊列

若是不指定x-dead-letter-routing-key參數,則使用原來的routingkey圖片

參考資料

  1. RabbitMQ之TTL(Time-To-Live 過時時間)
  2. RabbitMQ之mandatory和immediate
  3. RabbitMQ(四)RabbitMQ死信郵箱(DLX)
  4. RabbitMQ Dead Letter Exchanges
相關文章
相關標籤/搜索