我是靠谱客的博主 火星上樱桃,最近开发中收集的这篇文章主要介绍使用rabbitmq 实现延迟消费实现方式参考文献,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

使用场景介绍

1、发版时经常需要不停机发版,遇到mq消费者,消费一半停机就会出现消息丢失(没有使用手动确认的情况)

2、例如支付场景,准时支付、超过未支付将执行不同的方案,其中超时未支付可以看做一个延时消息。

3、例如滴滴、淘宝的自动评价都是类似场景(不一定是用的什么技术)

我是发版的情况遇到了

可能有人会问了,mq支持手动确认啊,为什么不使用确认机制呢?
1、由于用的是Spring 的RabbitListener注解,无法使用手动确认机制
2、也是最主要的原因是我们使用mq的场景

(类似于假如我做一个事情需要两步完成,每一步完成都会收钱。那么就会出现,第一步完成后,停机了,假如使用消息重发就会造成浪费第一步完成的钱)

实现方式

开始想到的是发版时,可以将消息发到队列里,然后消费者不要马上消费,等一定的时间再来消费这一消息。

在网上找资料找到两种实现方式:

1、使用插件

在rabbitmq 3.5.7及以上的版本提供了一个插件(rabbitmq-delayed-message-exchange)来实现延迟队列,而我们公司mq是单独管理的,所以这种方式直接pass

2、使用两个特性

AMQP和RabbitMQ本身没有直接支持延迟队列功能,但是可以通过以下特性模拟出延迟队列的功能。但是我们可以通过RabbitMQ的两个特性来曲线实现延迟队列。

Time To Live(TTL)

RabbitMQ可以针对Queue和Message设置 x-message-tt,来控制消息的生存时间,如果超时,则消息变为dead letter
RabbitMQ针对队列中的消息过期时间有两种方法可以设置。
A: 通过队列属性设置,队列中所有消息都有相同的过期时间。
B: 对消息进行单独设置,每条消息TTL可以不同。
如果同时使用,则消息的过期时间以两者之间TTL较小的那个数值为准。消息在队列的生存时间一旦超过设置的TTL值,就成为dead letter

Dead Letter Exchanges(DLX)

RabbitMQ的Queue可以配置x-dead-letter-exchange 和x-dead-letter-routing-key(可选)两个参数,如果队列内出现了dead letter,则按照这两个参数重新路由。

x-dead-letter-exchange:出现dead letter之后将dead letter重新发送到指定exchange
x-dead-letter-routing-key:指定routing-key发送
队列出现dead letter的情况有:
消息或者队列的TTL过期
队列达到最大长度
消息被消费端拒绝(basic.reject or basic.nack)并且requeue=false

利用DLX,当消息在一个队列中变成死信后,它能被重新publish到另一个Exchange。这时候消息就可以重新被消费。

示例代码

初始化过期队列的代码

@Bean
    public Queue signQueueStore() {
        Map<String, Object> arguments = new HashMap<>();
        arguments.put("x-dead-letter-exchange", exchange);
        arguments.put("x-dead-letter-routing-key", signKey);
        arguments.put("x-message-ttl",300000);
        Queue queue = new Queue(signQueueStore,true,false,false,arguments);
        System.out.println("arguments :" + queue.getArguments());
        return queue;
    }

绑定过期队列的代码

@Bean
    public Binding  signStoreBinding() {
        return BindingBuilder.bind(signQueueStore()).to(defaultExchange()).with(signKeyStore);
    }

初始化正常队列的代码和绑定普通队列的代码

@Bean
    public Queue signQueue() {
        return new Queue(signQueue);
    }

    @Bean
    public Binding signBinding(Queue signQueue, DirectExchange defaultExchange) {
        /** 将队列绑定到交换机 */
        return BindingBuilder.bind(signQueue).to(defaultExchange).with(signKey);
    }

其他发送与消费不变

在重启时将消息发送到过期队列,在重启完成后,消息发送到正常队列,过期队列消息过期后会自动路由到正常队列进行消费。(可以设置一个标志,判断该标志位重启状态,则发到过期队列,为正常状态发送到正常队列)

参考文献

rabbitmq 实现延迟队列的两种方式

最后

以上就是火星上樱桃为你收集整理的使用rabbitmq 实现延迟消费实现方式参考文献的全部内容,希望文章能够帮你解决使用rabbitmq 实现延迟消费实现方式参考文献所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部