DLX ,Dead-Letter-Exchange利用DLX,当消息在一个队列中变成死信(dead message)之后,它能被重新publish到另外一个Exchange,这个Exchange就是DLX。
消息变成死信有以下几种情况:
1.消息被拒绝(basic.reject/basic.nack)并且requeue=false
2.消息TTL过期。。
3.队列达到最大长度。
DLX也是一个正常的Exchange,和一般的Exchange没有区别,它能在任何的队列上被指定,实际上就是设置某个队列的属性。 当这个队列中有死信的时,RabbitMQ就会自动的将这个消息重新发布到设置的Exchange上去,进二被路由到另外一个队列。
可以监听这个队列中消息做相应的处理,这个特性可以弥补RabbitMQ3.0以前支持的immediate参数的功能。
死信队列的设置:
1 首先需要设置死信队列的Exchange和queue,然后绑定:
Exchange:dlx.exchange
Queue:dlx.queue
RoutingKey:#
2 然后进行正常声明交换机、队列、绑定,只不过我们需要在对别加上一个参数即可:arguments.put("x-dead-letter-exchange","dlx.exchange")。这样消息在过期、qequeue、队列达到最大长度时,消息就可以直接路由到死信队列!
消费者端代码
package com.star.movie.dlx;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.DefaultConsumer;
import com.rabbitmq.client.Envelope;
import java.io.IOException;
/**
* @Description:
* @author:kaili
* @Date: 2019-04-22 20:10
**/
public class MyDlxConsumer extends DefaultConsumer {
private Channel channel;
public MyDlxConsumer(Channel channel) {
super(channel);
this.channel = channel;
}
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
System.err.println("----------- consume message ----------");
System.err.println("consumerTag: " + consumerTag);
System.err.println("envelope: " + envelope);
System.err.println("properties: " + properties);
System.err.println("body: " + new String(body));
}
}
package com.star.movie.dlx;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.star.movie.common.Constant;
import java.util.HashMap;
import java.util.Map;
/**
* @Description:
* @author:kaili
* @Date: 2019-04-22 20:08
**/
public class DlxConsumer {
public static void main(String[] args) throws Exception{
Connection connection = Constant.getConnection();
Channel channel = connection.createChannel();
// 这就是一个普通的交换机 和 队列 以及路由
String exchangeName = "test_dlx_exchange";
String routingKey = "dlx.#";
String queueName = "test_dlx_queue";
channel.exchangeDeclare(exchangeName, "topic", true, false, null);
Map<String, Object> agruments = new HashMap<String, Object>();
agruments.put("x-dead-letter-exchange", "dlx.exchange");
//这个agruments属性,要设置到声明队列上
channel.queueDeclare(queueName, true, false, false, agruments);
channel.queueBind(queueName, exchangeName, routingKey);
//要进行死信队列的声明:
channel.exchangeDeclare("dlx.exchange", "topic", true, false, null);
channel.queueDeclare("dlx.queue", true, false, false, null);
channel.queueBind("dlx.queue", "dlx.exchange", "#");
channel.basicConsume(queueName, true, new MyDlxConsumer(channel));
}
}
生产者端代码
package com.star.movie.dlx;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.star.movie.common.Constant;
/**
* @Description:
* @author:kaili
* @Date: 2019-04-22 20:07
**/
public class DlxProducer {
public static void main(String[] args) throws Exception{
Connection connection = Constant.getConnection();
Channel channel = connection.createChannel();
String exchange = "test_dlx_exchange";
String routingKey = "dlx.save";
String msg = "Hello RabbitMQ DLX Message";
for(int i =0; i<1; i ++){
//设置消息有效期
AMQP.BasicProperties properties = new AMQP.BasicProperties.Builder()
.deliveryMode(2)
.contentEncoding("UTF-8")
.expiration("10000")
.build();
channel.basicPublish(exchange, routingKey, true, properties, msg.getBytes());
}
}
}
控制台效果
10s后:
来源:CSDN
作者:star2013yk
链接:https://blog.csdn.net/baidu_17450413/article/details/104536265