死信交换器结合消息过期机制一般用在“限时订单”业务场景
1.创建生产者DlxProducer
package com.rabbit.fisher.dlx;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import com.rabbitmq.client.ConnectionFactory;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*生产者
*/
public class DlxProducer
{
public final static String EXCHANGE_NAME="dlx_logs";
public final static String DLX_EXCHANGE_NAME="dlx_accept";
public static void main( String[] args ) throws IOException, TimeoutException {
//创建链接、连接到MQ
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//在信道中设置交换器
channel.exchangeDeclare(EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
//在消费者中申明队列
//申明路由键及消息体
String[] routeKeys={"rabbit","rocket","kafka"};
for (int i = 0; i < 3; i++) {
String route = routeKeys[i % 3];
String msg = "Hello World" + (i+1);
//发布消息(设置交换器、路由键、参数、消息内容)
channel.basicPublish(EXCHANGE_NAME, route, null, msg.getBytes());
System.out.println("Send:" + route + ";" + msg);
}
//关闭信道
channel.close();
//关闭连接
connection.close();
}
}
2.创建消费者MakeDlxConsumer,只消费rabbit路由键绑定的消息,其他消息拒绝消费进入死信队列;并设置死信交换器
package com.rabbit.fisher.dlx;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeoutException;
/**
*普通消费者,不消费的消息将进入死信队列
*/
public class MakeDlxConsumer
{
public static void main( String[] args ) throws IOException, TimeoutException {
//创建链接、连接到MQ
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建信道
final Channel channel = connection.createChannel();
//在信道中设置交换器
channel.exchangeDeclare(DlxProducer.EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
Map<String, Object> map = new HashMap<>();
//设置死信交换器
map.put("x-dead-letter-exchange", DlxProducer.DLX_EXCHANGE_NAME);
//死信路由键,会替换消息原来的路由键
map.put("x-dead-letter-routing-key", "deal");
//申明队列
String queueName = "make_dlx";
channel.queueDeclare(queueName, false, false, false, map);
//绑定#
channel.queueBind(queueName, DlxProducer.EXCHANGE_NAME, "#");
System.out.println("waiting for message ......");
//申明一个消费者
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
//如果是rabbit的消息就手动确认
if (envelope.getRoutingKey().equals("rabbit")) {
System.out.println("Receive[" + envelope.getRoutingKey() + "]" + message);
//单条确认
channel.basicAck(envelope.getDeliveryTag(), false);
}else {
//如果是其他消息就拒绝(requeue=false),成为死信消息
System.out.println("Reject[" + envelope.getRoutingKey() + "]" + message);
//拒绝,并不重新投递
channel.basicReject(envelope.getDeliveryTag(), false);
}
}
};
channel.basicConsume(queueName, false, consumer);
}
}
3.创建消费者MakeDlxConsumer,只消费死信队列内的消息
package com.rabbit.fisher.dlx;
import com.rabbitmq.client.*;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
/**
*普通消费者,消费死信队列dlx_consumer的消息
*/
public class DlxConsumer
{
public static void main( String[] args ) throws IOException, TimeoutException {
//创建链接、连接到MQ
ConnectionFactory connectionFactory = new ConnectionFactory();
//设置连接工厂的连接地址(默认端口5672)
connectionFactory.setHost("192.168.42.111");
//设置虚拟主机
connectionFactory.setVirtualHost("fisher");
//设置用户名
connectionFactory.setUsername("fisher");
//设置密码
connectionFactory.setPassword("123456");
//创建连接
Connection connection = connectionFactory.newConnection();
//创建信道
Channel channel = connection.createChannel();
//在信道中设置交换器
channel.exchangeDeclare(DlxProducer.DLX_EXCHANGE_NAME, BuiltinExchangeType.TOPIC);
//申明队列
String queueName = "dlx_consumer";
channel.queueDeclare(queueName, false, false, false, null);
//绑定#
channel.queueBind(queueName, DlxProducer.DLX_EXCHANGE_NAME, "#");
System.out.println("waiting for message ......");
//申明一个消费者
final Consumer consumer = new DefaultConsumer(channel){
@Override
public void handleDelivery(String consumerTag, Envelope envelope, AMQP.BasicProperties properties, byte[] body) throws IOException {
String message = new String(body, "UTF-8");
System.out.println("Receive dead letter[" + envelope.getRoutingKey() + "]" + message);
}
};
//消费者自动确认
channel.basicConsume(queueName, true, consumer);
}
}