1、概述
DLX,全称为Dead-Letter-Exchange , 可以称之为死信交换机,也有人称之为死信邮箱。当消息在一个队列中变成死信(dead message)之后,它能被重新发送到另一个交换机中,这个交换机就是DLX ,绑定DLX的队列就称之为死信队列。
消息变成死信,可能是由于以下的原因:
- 消息被拒绝
- 消息过期
- 队列达到最大长度
DLX也是一个正常的交换机,和一般的交换机没有区别,它能在任何的队列上被指定,实际上就是设置某一个队列的属性。当这个队列中存在死信时,Rabbitmq就会自动地将这个消息重新发布到设置的DLX上去,进而被路由到另一个队列,即死信队列。
要想使用死信队列,只需要在定义队列的时候设置队列参数 x-dead-letter-exchange 指定交换机即可。
2、应用场景
延迟下单,比如买票和外卖订单,有延迟多少分钟内下单,超过这个时间就将该订单移除出队列到死信队列中,作另外的处理。
3、简单实现
在生产者工程配置死信队列和普通队列
Config配置
package com.example.service;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.BindingBuilder;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.HashMap;
import java.util.Map;
@Configuration
public class Config {
@Bean
public DirectExchange directExchange(){
return new DirectExchange("ttl_exchange",true,false);
}
@Bean
public Queue TtlQueue(){
Map<String,Object> args = new HashMap<>();
// 设置队列过期时间,一定是int类型
args.put("x-message-ttl",5000);
// 配置死信队列
args.put("x-dead-letter-exchange","dead_exchange");
args.put("x-dead-letter-routing-key","dead");
return new Queue("ttl.queue",true,false,false,args);
}
@Bean
public Binding ttlBinding(){
return BindingBuilder.bind(TtlQueue()).to(directExchange()).with("ttl");
}
// 定义死信队列
@Bean
public DirectExchange deadExchange(){
return new DirectExchange("dead_exchange",true,false);
}
@Bean
public Queue deadQueue(){
return new Queue("dead.queue");
}
@Bean
public Binding deadBinding(){
return BindingBuilder.bind(deadQueue()).to(deadExchange()).with("dead");
}
}
OrderService
@Service
public class OrderService {
@Autowired
private RabbitTemplate rabbitTemplate;
public void send(String msg){
rabbitTemplate.convertAndSend("ttl_exchange","ttl",msg);
}
}
测试类
@SpringBootTest
class RabbitmqDirectProducerApplicationTests {
@Autowired
private OrderService orderService;
@Test
void contextLoads() {
orderService.send("测试内容11145");
}
}
启动测试类
消息在过了5s后被移出ttl.queue到死信队列dead.queue中