死信队列(DLX dead-letter-exchange)
死信
(1)消息被拒绝并且没有重新放到队列中
(2)消息超时 (通过Arguments对象设置x-message-ttl Time To Live简称TTL)
(3)超过队列长度限制的消息
通过这种特性可以做延时队列。
使用场景
分布式应用系统因为发送超时情况下,通过自消费延时发送做数据同步处理。
优点:
1.可以避免专门使用定时任务做轮循操作。
2.应用系统分布式部署,起到了分布式定时任务系统作用
缺点:
无法定时定点执行。
延时队列
这里的延时队列可以通过两种方式来实现:
(1)设置消息的有效时间
(2)设置队列的有效时间,即消息没有被消费,从该队列移除。
如何设置
@Data
@Configuration
@ConfigurationProperties(prefix = "spring.rabbitmq")
@PropertySource(value = "classpath:rabbitmq.properties")
public class RabbitMQConfig {
org.slf4j.Logger logger = LoggerFactory.getLogger(this.getClass());
private String host;
private int port;
private String username;
private String password;
private String virtualHost;
@Bean public CachingConnectionFactory cachingConnectionFactory() {
CachingConnectionFactory factory = new CachingConnectionFactory();
factory.setHost(host);
factory.setPort(port);
factory.setUsername(username);
factory.setPassword(password);
factory.setVirtualHost(virtualHost);
factory.setConnectionTimeout(20000);
//开启confirm机制(确保消息能够到达Exchange)
factory.setPublisherConfirms(true);
//开启return机制(确保消息能够路由到Queue)
factory.setPublisherReturns(true);
return factory;
}
@Bean public RabbitAdmin rabbitAdmin(CachingConnectionFactory cachingConnectionFactory) {
return new RabbitAdmin(cachingConnectionFactory);
}
//声明一个绑定有时效的Queue的Exchange
@Bean public DirectExchange delayExchange() {
// 1.队列名称;
// 2.是否持久化;
// 3.是否自动删除(没有被使用的时候,直接删除该队列)
return new DirectExchange("delay-exchange", true, false);
}
//声明一个不被消费者消费的队列
@Bean public Queue delayQueue(){
Map<String, Object> map = new HashMap<>(3);
//设置消息在队列中存活时间
map.put("x-message-ttl", 100000);
//设置消息成为死信后被转发到的交换机
map.put("x-dead-letter-exchange", "dead-exchange");
//设置交换机的路由键
map.put("x-dead-letter-routing-key", "dead-exchange-routing-key");
// 1.队列名称;
// 2.是否持久化;
// 3.是否独占(被当前连接使用);
// 4.是否自动删除(没有被使用的时候,直接删除该队列)
// 5.拓展参数(可以通过rabbitmq admin客户端查看有哪些参数)
return new Queue("delay-queue", true, false, false, map);
}
//绑定延时队列、交换机
@Bean public Binding delayBinding(){
return new Binding("delay-queue", Binding.DestinationType.QUEUE,"delay-exchange" ,
"delay-exchange-routing-key", null);
}
//声明死信的Exchange
@Bean public DirectExchange deadExchange(){
return new DirectExchange("dead-exchange", true, false);
}
//声明死信消费的队列
@Bean public Queue deadQueue(){
return new Queue("dead-queue", true, false, false);
}
//绑定死信队列、交换机
@Bean public Binding deadBinding(){
return new Binding("dead-queue", Binding.DestinationType.QUEUE,"dead-exchange" ,
"dead-exchange-routing-key", null);
}
@Bean public RabbitTemplate rabbitTemplate(CachingConnectionFactory cachingConnectionFactory) {
RabbitTemplate rabbitTemplate = new RabbitTemplate(cachingConnectionFactory);
rabbitTemplate.setConfirmCallback((CorrelationData correlationData, boolean ack, String cause) -> {
logger.error("correlationData---->" + correlationData);
logger.error("ack---->" + ack);
logger.error("cause---->" + cause);
});
//开启强制性委托,不设置,returnCallback机制不起作用
rabbitTemplate.setMandatory(true);
rabbitTemplate.setReturnCallback((Message message, int replyCode, String replyText,
String exchange, String routingKey)->{
logger.error("message---->" + new String(message.getBody()));
logger.error("replyCode---->" + replyCode);
logger.error("replyText---->" + replyText);
logger.error("exchange---->" + exchange);
logger.error("routingKey---->" + routingKey);
});
return rabbitTemplate;
}
}