延时消息
- 延迟消息
- 死信交换机
- 延迟消息的插件
延迟消息
生产者发送消息时指定一个时间,消费者不会立刻收到消息,而在指定时间之后才收到消息
比如说演唱会的票,抢上了但是迟迟未支付,但是库存已经占用,就需要用到延迟消息
使用延时消息,但我们抢到票后发送消息到消息队列中,这时消息延时,假定30分钟,等到30分钟之后消息到达交易服务,如果这时还没有支付,就将这个服务挂掉
如何实现延时消息:
死信交换机
当一个队列中的消息满足下列情况之一,就会成为死信(dead letter):
- 消费者使用basic.reject或basic.nack声明消费失败,并且消息的requeue参数设置为false(设置消息不重新排队)
- 消息是一个过期消息(到达队列或消息本身设置的过期时间),超时无人消费
- 要投递的队列消息堆积满了,最早的消息可能成为死信
如果队列通过dead-letter-exchange
属性指定了一个交换机,那么该队列中的死信就会投递到这个交换机中,这个交换机称为死信交换机(DLX)
延迟消息的插件
RabbitMQ的官方也推出了一个插件,原生支持延迟消息功能。该插件的原理是设计了一种支持延迟消息功能的交换机当消息投递到交换机后可以暂存一定时间,到期后再投递到队列。
安装 rabbitmq-delayed-message-exchange
插件
配置延迟交换机:
第一种:注解配置
@RabbitListener(bindings=@QueueBinding(
value=@Queue(name="delay.queue",durable="true"),
exchange=@Exchange(name="delay.direct",delayed="true"),
key="delay"))
第二种:配置设置
@Bean
public DirectExchange delayExchange(){
return ExchangeBuilder
.directExchange("delay.direct")
.delayed() //设置属性为true
.durable(true)
.build();
}
如何发送延迟消息:通过消息头x-delay来设置过期时间:
@Test
void test(){
String message="hello";
rabbitTemplate.convertAndSend("delay.direct","delay",message,new MessagePostProcessor(){
@Override
public Message postProcessMessage(Message message) throws Exception{
message.getMessageProperties().setDelay(5000);
return message;
}
})
}