九、消息可靠性(延迟消息)

0、需求

延迟消息:生产者发送消息时指定一个时间,消费者不会立即收到消息,而是在指定时间之后才收到消息。
延迟任务:设置在一定时间之后才执行的任务。

在这里插入图片描述

1、死信交换机

● 当一个队列中的消息满足下列情况之一时,就好成为 死信(dead letter)

  • 消费者使用 basic.reject 或 basic.nack 声明消费失败,并且消息的 requeue 参数设置为 false
  • 消息是一个过期消息(达到了队列或消息本身设置的过期时间),超时无人消费
  • 要投递的队列消息堆积满了,最早的消息可能成为死信

如果队列通过 x-dead-letter-exchange 属性指定了一个交换机,那么该队列中的死信就会投递到这个交换机中,这个交换机成为 死信交换机 (Dead Letter Exchange,简称 DLX)

在这里插入图片描述

● 配置类

@Configuration
public class MyRabbitConfig {

    @Bean
    public FanoutExchange mySimpleFanoutExchange(){
        return new FanoutExchange("mySimpleFanoutExchange");
    }

    @Bean
    public Queue mySimpleFanoutQueue(){
        // 设置队列的死信交换机
        return QueueBuilder.durable("mySimpleFanoutQueue").withArgument("x-dead-letter-exchange", "dlxFanoutExchange").build();
    }

    @Bean
    public Binding mySimpleBinding(){
        return BindingBuilder.bind(mySimpleFanoutQueue()).to(mySimpleFanoutExchange());
    }

    @Bean
    public FanoutExchange dlxFanoutExchange(){
        return new FanoutExchange("dlxFanoutExchange");
    }

    @Bean
    public Queue dlxFanoutQueue(){
        return new Queue("dlxFanoutQueue");
    }

    @Bean
    public Binding myDlxBinding(){
        return BindingBuilder.bind(dlxFanoutQueue()).to(dlxFanoutExchange());
    }
}

● 发送者

Message msg = MessageBuilder
	.withBody("dlx message".getBytes(StandardCharsets.UTF_8))
	.setExpiration("10000") // 设置过期时间(ms)
	.build();

// 参数:交换机,routingKey, 消息
rabbitTemplate.convertAndSend("mySimpleFanoutExchange", null, msg);

● 消费者

// 只监听死信队列已达到想要的效果
@RabbitListener(queues = "dlxFanoutQueue")
public void dlxFanoutQueueListener(String msg) {
    System.out.println("\n死信队列接到了死信交换机的消息:" + msg);
}

2、延迟消息插件

RabbitMQ 官方推出了一个插件,原生支持延迟消息功能。该插件的原理是设计了一种支持延迟消息功能的交换机,当消息投递到交换后可暂存一定时间,到期后再投递到队列。

点击访问 DelayExchange 插件

Linux服务器使用可参考 RabbitMQ 安装延迟队列插件
注:只适用于定时较短的延迟消息,不然会大量损耗服务器性能

2.1、创建延迟队列

// 1、配置类
@Bean
public FanoutExchange delayExchange(){
    return (FanoutExchange)ExchangeBuilder.
            fanoutExchange("delayExchange")
            .delayed() // 设置delay=true
            .build();
}

// 2、@RabbitListener
@RabbitListener(bindings = @QueueBinding(
        value = @Queue(name = "delayQueue", durable = "true"),
        exchange = @Exchange(
                name = "delayExchange",
                type = ExchangeTypes.FANOUT,
                delayed = "true" // 设置delay=true
        )
))
public void myDelayListener(String msg) {
    // ...
}

2.2、发送延迟消息

rabbitTemplate.convertAndSend("delayExchange", null, "message", new MessagePostProcessor() {
    @Override
    public Message postProcessMessage(Message message) throws AmqpException {
        // 设置延迟消息属性
        message.getMessageProperties().setDelay(10000);
        return message;
    }
});
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

纯纯的小白

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值