Springboot整合RabbitMQ–进阶使用
延迟队列
方案一:死信队列+TTL
1.声明死信交换机和死信队列
@Component
public class DeadListener {
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "dead.queue"),
exchange = @Exchange(name = "dead.exchange"),
key = {"dead.ttl"}
))
public void deadListener(String msg){
//执行相应处理
System.out.println("死信队列执行:"+ msg);
}
}
2.声明普通队列(并指定ttl)并为其指定死信交换机(注意:将普通交换机和普通队列绑定的routingKey是死信交换机和死信队列绑定的routingKey)
//声明绑定死信队列的普通队列
@Bean
public Queue directQueue(){
return QueueBuilder.durable("d1.queue") //指定队列名称并持久化
.deadLetterExchange("dead.exchange") //指定死信交换机
.ttl(10000) //设置队列超时时间 10s
.build();
}
//声明普通交换机
@Bean
public DirectExchange directExchange(){
return new DirectExchange("d1.exchange");
}
//将普通交换机与普通队列绑定
@Bean
public Binding bindingQueue1(Queue directQueue, DirectExchange directExchange){
return BindingBuilder.bind(directQueue).to(directExchange).with("dead.ttl");
}
3.发送消息(注意:routingKey是死信交换机和死信队列绑定的routingKey)
@Test
public void testDead(){
//消息
String msg = "hello dead consume";
//交换机
String exchange = "d1.exchange";
//发送消息
rabbitTemplate.convertAndSend(exchange,"dead.ttl",msg);
System.out.println("消息发送成功");
}
这里可以看出,确实实现了延迟效果。
方案二:利用DelayExchange插件
DelayExchange需要将一个交换机声明为delayed类型。当我们发送消息到delayExchange时,流程如下:
- 接收消息
- 判断消息是否具备x-delay属性
- 如果有x-delay属性,说明是延迟消息,持久化到硬盘,读取x-delay值,作为延迟时间
- 返回routing not found结果给消息发送者
- x-delay时间到期后,重新投递消息到指定队列
1.声明DelayExchange交换机
@RabbitListener(bindings = @QueueBinding(
value = @Queue(name = "delay.queue"),
exchange = @Exchange(name = "delay.direct",delayed = "true"),
key = "delay"
))
public void deadListener2(String msg){
log.info("死信队列执行:"+msg.toString());
}
2.发送消息(注意:在消息参数中必须设置x-delay)
@Test
public void testDead2(){
//消息
String msgContent = "hello";
//交换机
String exchange = "delay.direct";
//发送消息
rabbitTemplate.convertAndSend(exchange,"delay",msgContent,msg->{
msg.getMessageProperties().setHeader("x-delay",5000); //设置延时5s
return msg;
});
log.info("消息发送成功");
}
可以看出,基于插件也可以实现延迟效果