基础的Demo代码死信队列本质上还是个队列,不过它不用我们主动的去传递消息给它,在一定条件下,其它的队列会将消息传递给它,比如说给一个正常的队列绑定一个死信队列,同时给这个队列设置过期时间,如果到了过期时间依旧没有被消费,那么就会自动转入到死信队列中。
package life.hopeurl.dead_letter;
import com.rabbitmq.client.AMQP;
import com.rabbitmq.client.BuiltinExchangeType;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import life.hopeurl.utils.RabbitMQUtils;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;
public class DeadLetterQueue {
//私信队列
private static final String DEAD_LETTER_QUEUE="dead_letter_queue";
//死信队列交换机
private static final String DEAD_LETTER_EXCHANGE="dead_letter_exchange";
//死信队列routing_key
private static final String DEAD_LETTER_ROUTING_KEY="dead_letter_routing_key";
//正常的队列
private static final String NORMAL_QUEUE="normal_queue";
//正常交换机
private static final String NORMAL_EXCHANGE="normal_exchange";
//正常的routing_key
private static final String NORMAL_ROUTING_KEY="normal_routing_key";
public static void main(String[] args) throws Exception {
Connection connection = RabbitMQUtils.getConnection();
Channel channel = connection.createChannel();
//创建死信队列和死信交换机
channel.queueDeclare(DEAD_LETTER_QUEUE,true,false,false,null);
channel.exchangeDeclare(DEAD_LETTER_EXCHANGE, BuiltinExchangeType.DIRECT);
//将交换机和队列进行绑定
channel.queueBind(DEAD_LETTER_QUEUE,DEAD_LETTER_EXCHANGE,DEAD_LETTER_ROUTING_KEY);
//设置普通的队列参数
Map arguments=new HashMap<>();
arguments.put("x-dead-letter-exchange",DEAD_LETTER_EXCHANGE);
arguments.put("x-dead-letter-routing-key",DEAD_LETTER_ROUTING_KEY);
//开始创建普通的队列以及交换机
channel.queueDeclare(NORMAL_QUEUE,true,false,false,arguments);
channel.exchangeDeclare(NORMAL_EXCHANGE,BuiltinExchangeType.DIRECT);
channel.queueBind(NORMAL_QUEUE,NORMAL_EXCHANGE,NORMAL_ROUTING_KEY);
//配置消息的过期时间
AMQP.BasicProperties bp=new AMQP.BasicProperties().builder().expiration("20000").build();
//开始发送信息
channel.basicPublish(NORMAL_EXCHANGE,NORMAL_ROUTING_KEY,bp,"我是测试死信队列的消息".getBytes(StandardCharsets.UTF_8));
}
}
在上面的代码中,给正常的队列的一个消息设置20秒的过期时间,如果在过期时间内没有被消费的话,那么到过期的时候就会自动转入到死信队列中。结合这一点,死信队列是可以被用于支付模块中的超时订单自动取消的。
在SpringBoot 中编写监听器
package life.hopeurl.service;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
@Component
@Transactional
public class DeadLetterService {
@RabbitListener(queues = "dead_letter_queue")
public void timeoutOrderCancel(String message){
System.out.println(message);
}
}
(未完待续~)



