说明
参考链接:布碗RabbitMQ学习(十三)
小目标青年Springboot 整合RabbitMq
正文
概述
由mq的死信队列实现
DLX(Dead Letter Exchange),死信交换器。当队列中的消息被拒绝、或者过期会变成死信,死信可以被重新发布到另一个交换器,这个交换器就是DLX,与DLX绑定的队列称为死信队列。
通过"x-dead-letter-exchange"设置到期后转发的交换机,"x-dead-letter-routing-key"设置到期后转发的路由键
导入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
</dependency>
配置类
package icu.hezhilin.config;
import org.springframework.amqp.core.*;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class DirectRabbitConfig {
/**
* 队列 起名:TestDirectQueue
*/
@Bean
public Queue testDirectQueue() {
/**
* durable:是否持久化,默认是false,持久化队列:会被存储在磁盘上,当消息代理重启时仍然存在,暂存队列:当前连接有效
* exclusive:默认也是false,只能被当前创建的连接使用,而且当连接关闭后队列即被删除。此参考优先级高于durable
* autoDelete:是否自动删除,当没有生产者或者消费者使用此队列,该队列会自动删除。
* return new Queue("TestDirectQueue",true,true,false);
* 一般设置一下队列的持久化就好,其余两个就是默认false
*/
return new Queue("TestDirectQueue",true);
}
/**
*
* Direct交换机 起名:TestDirectExchange
*/
@Bean
DirectExchange testDirectExchange() {
return ExchangeBuilder.directExchange("TestDirectExchange")
.durable(true)
.build();
}
/**
* 将队列与交换机绑定
*/
@Bean
Binding bindingDirect(DirectExchange testDirectExchange,Queue testDirectQueue){
return BindingBuilder.bind(testDirectQueue)
.to(testDirectExchange)
.with("TestDirectRouting");
}
/**
* 延迟队列队列所绑定的交换机
*/
@Bean
DirectExchange TestTtlDirect() {
return (DirectExchange) ExchangeBuilder
.directExchange("TestTtlDirectExchange")
.durable(true)
.build();
}
/**
* 延迟队列(死信队列)
*/
@Bean
public Queue TestTtlQueue() {
return QueueBuilder
.durable("TestTtlDirectQueue")
.withArgument("x-dead-letter-exchange", "TestDirectExchange")//到期后转发的交换机
.withArgument("x-dead-letter-routing-key", "TestDirectRouting")//到期后转发的路由键
.build();
}
/**
* 将延迟队列绑定到交换机
*/
@Bean
Binding TestTtlBinding(DirectExchange TestTtlDirect,Queue TestTtlQueue){
return BindingBuilder
.bind(TestTtlQueue)
.to(TestTtlDirect)
.with("TestTtlDirectRouting");
}
}
生产者发送消息
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.text.SimpleDateFormat;
import java.util.Date;
@RestController
public class SendMessageController {
@Autowired
RabbitTemplate rabbitTemplate;
//发送消息到正常队列
@GetMapping("/sendDirectMessage")
public String sendDirectMessage(@RequestParam String message) {
SimpleDateFormat Dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(Dateformat.format(new Date())+":发送消息");
//将消息携带绑定键值:TestDirectRouting 发送到交换机TestDirectExchange
rabbitTemplate.convertAndSend("TestDirectExchange", "TestDirectRouting", message);
return "ok";
}
//发送消息到死信队列
@GetMapping("/sendDelayMessage")
public String sendDelayMessage(@RequestParam String message,@RequestParam(value = "delayTimes") long delayTimes) {
SimpleDateFormat Dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(Dateformat.format(new Date())+":发送消息");
//将消息携带绑定键值:TestTtlDirectRouting 发送到交换机TestTtlDirectExchange
rabbitTemplate.convertAndSend("TestTtlDirectExchange", "TestTtlDirectRouting", message, new MessagePostProcessor() {
@Override
public Message postProcessMessage(Message message) throws AmqpException {
message.getMessageProperties().setExpiration(String.valueOf(delayTimes));
return message;
}
});
return "ok";
}
}
消费者打印消息
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.text.SimpleDateFormat;
import java.util.Date;
@Component
@RabbitListener(queues = "TestDirectQueue")//监听TestDirectQueue队列
public class AcceptMessageController {
@Autowired
RabbitTemplate rabbitTemplate;
@RabbitHandler//执行方法
public void cancelDirectMessage(String testMessage) {
SimpleDateFormat Dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
System.out.println(Dateformat.format(new Date())+":消费者收到消息 : " + testMessage);
}
}