本文共 2001 字,大约阅读时间需要 6 分钟。
在消息队列系统中,死信(Dead Letter)是指那些无法被正常消费的消息。消息成为死信的条件包括:
basic.reject
或basic.nack
声明消费失败,并且消息的requeue
参数设置为false
。当一个队列配置了dead-letter-exchange
属性并指定了一个交换机时,队列中的死信会被投递到这个交换机中。这个交换机被称为死信交换机(Dead Letter Exchange,简称DLX)。死信交换机就像一个垃圾桶,收集无法被正确处理的消息。
TTL(Time-To-Live)是消息或队列设置的超时时间。如果消息在TLT超时后仍未被消费,则会变为死信。TTL可以设置在两个地方:
延迟队列是一种通过TTL和死信交换机实现的消息模式,允许消息在指定时间后被消费者接收。这种模式的主要场景包括:
为了实现延迟队列,RabbitMQ提供了DelayExchange插件。插件原理如下:
x-delay
属性。x-delay
属性,消息会被持久化到硬盘,等待指定时间再重新投递到指定队列。基于Docker安装RabbitMQ时,可以通过以下步骤安装插件:
在Spring应用中,可以通过注解声明延迟队列:
@RabbitListener(bindings = @QueueBinding( value = @Queue(name = "delay_queue", durable = "true"), exchange = @Exchange(name = "delay_exchange", type = DirectExchange.class), key = "delay_key"))public void processDelayMessage(String message) { // 消息处理逻辑}
在配置类中,可以手动声明交换机和队列:
@Configurationpublic class DelayQueueConfig { @Bean public DirectExchange delayExchange() { return new DirectExchange("delay_exchange"); } @Bean public Queue delayQueue() { return new Queue("delay_queue", true) .ttl(5000L) // 队列超时时间 .deadLetterExchange("dead_exchange") .deadLetterRoutingKey("dead_key"); } @Bean public Binding delayBinding() { return BindingBuilder.bind(delayQueue()) .to(delayExchange()) .with("delay_key"); }}
发送消息时,需要在消息头中携带x-delay
属性,指定延迟时间:
Message message = MessageBuilder .withBody("hello, delay!".getBytes(StandardCharsets.UTF_8)) .setDelay(20000L) // 延迟时间 .build();rabbitTemplate.convertAndSend("delay_exchange", "delay_key", message);
延迟队列通过TTL和死信交换机实现消息的延迟处理,适用于需要在指定时间后自动触发某些操作的场景。
转载地址:http://xmfuk.baihongyu.com/