rabbitmq中的消息当遇到以下几种情况,会变成死信:
消息被拒绝(basic.reject / basic.nack),并且requeue = false
消息TTL过期
队列达到最大长度
当一个队列中的消息变成死信,可以通过x-dead-letter-exchange配置一个交换器,让这些消息到另一个队列上处理
//正常队列配置
String myExchangeName = "myExchangeNameStr";
String myQueueName = "myQueueNameStr";
String myRoutingKey = "myRoutingKeyStr";
//死信队列配置
String dlxExchangeName = "dlxExchangeNameStr";
String dlxQueueName = "dlxQueueNameStr";
String dlxRoutingKey = "#";//匹配任何字符
Map<String, Object> arguments = new HashMap<String, Object>();
arguments.put("x-dead-letter-exchange",dlxExchangeName);//设置myQueueName队列的死信交换器为dlxExchangeName
arguments.put("x-message-ttl", 10000);//设置myQueueName队列中的消息10秒钟过期,用来测试死信队列是否能收到消息
//正常的队列绑定
channel.exchangeDeclare(myExchangeName, "direct");
channel.queueDeclare(myQueueName, true, false, false, arguments);//(队列名称,是否持久化,是否只能本连接使用,当消费者连接断开是否自动删除队列,其他参数)
channel.queueBind(myQueueName, myExchangeName, myRoutingKey);
//死信队列绑定
channel.exchangeDeclare(dlxExchangeName, "topic", true, false, null);
channel.queueDeclare(dlxQueueName, true, false, false, null);
channel.queueBind(dlxQueueName, dlxExchangeName, dlxRoutingKey);//经过交换器dlxExchangeName的消息,不管RoutingKey是任何字符,都会发送到队列dlxQueueName上
String message = "myMessage";
channel.basicPublish(myExchangeName, "myRoutingKeyStr", MessageProperties.PERSISTENT_TEXT_PLAIN, message.getBytes());
//等10秒后,myQueueName队列里的消息没被消费,由于超时会发到死信队列,这时消费死信队列dlxQueueName就能得到消息了。