关于后端:RabbitMQ高级之消息限流与延时队列

41次阅读

共计 3717 个字符,预计需要花费 10 分钟才能阅读完成。

人生终将是场单人旅途,孤单之前是迷茫,孤单过后是成长。

楔子

本篇是音讯队列 RabbitMQ 的第五弹。

上篇原本打算讲述 RabbitMQ 的一些高级用法:

  • 如何保障音讯的可靠性?
  • 音讯队列如何进行限流?
  • 如何设置延时队列进行延时生产?

最终因为篇幅缘故,上篇只讲了 如何保障音讯的可靠性?,本篇将会把剩下两个讲完,本篇也可能是 RabbitMQ 系列的最初一篇了~

我所讲的知识点在工作中基本上也够用了,心愿大家好好消化。

旧坑填上之后可能会缓缓开新坑了,同时因为当初到九月中旬这段时间我有一场考试须要筹备,所以文章更新可能会比较慢,然而一周一更算是最低限度把,心愿大家多多担待。

祝有好播种,先赞后看,高兴有限。

本文代码: 码云地址 GitHub 地址

1. ???? 音讯队列如何限流?

音讯队列限流是指在服务器面临巨额流量时,为了进行自保,进行的一种救急措施。

因为微小的流量代表着十分多的音讯,这些音讯如果多到服务器解决不过去就会造成服务器瘫痪,影响用户体验,造成不良影响。

所以要进行一次降级操作,把解决不了的流量断绝在零碎之外,防止它们打垮零碎。

基本上任何一个音讯队列都无限流的性能,明天咱们就来看看在 RabbitMQ 之中进行限流具体应该怎么做?

RabbitMQ 提供了一种 QOS(服务质量保障) 性能,即在非主动确认音讯的前提下,如果肯定数目的音讯还未被生产确认,则不进行新音讯的生产。


spring:
  rabbitmq:
    addresses: 127.0.0.1
    host: 5672
    username: guest
    password: guest
    virtual-host: /
    # 手动确认音讯
    listener:
      simple:
          acknowledge-mode: manual
          prefetch: 2

咱们只须要配置一下 rabbitmq.listener.simple 下的 prefetch 属性即可,为了演示不便我这里配置为两条,语义即为:如果队列中有两条以上未签收的音讯,则不进行新的音讯生产。

我往我的队列中发送三条信息,并不进行签收,来看看成果:

发送完显示咱们零碎中有三条 Ready 音讯,这代表这三条音讯还在队列中没有生产端去生产。

这时我关上生产端进行生产但仍旧不进行签收,接着来看成果:

unacked=2,ready=1,这就代表有两条音讯在服务端生产了然而没有签收,还有一条音讯还在队列中没有往服务端推送,因为咱们设置了prefetch=2,所以当初队列的最大同时在生产的音讯数量为 2,通过此种形式,咱们就实现了生产限流。

Tip : 这种形式下音讯肯定要进行手动签收,因为之前的文章中咱们讲过,主动签收是音讯一达到生产端就进行签收了,可能咱们的业务逻辑还没运行就曾经进行签收了,所以主动签收状态下开启限流简直没有作用。

2. ????RabbitMQ 控制台

上一节我的截图中,大家能够发现竟然呈现了可视化的界面,以往在我的截图中个别都是 DOS 命令操作台界面,但其实 RabbitMQ 是自带了可视化界面的插件的,咱们只须要开启即可。

在咱们的 RabbitMQ 中输出如下命令:rabbitmq-plugins.bat enable rabbitmq_management

就能够开启可视化页面了,紧接着拜访:http://localhost:15672/

默认用户名和明码都是 guest,间接登录即可。

很不便的控制台,大家能够本人试一下~

3. ????TTL 音讯 / 队列

TTL是 Time To Live 的缩写,也就是生存工夫的意思,RabbitMQ反对音讯的过期工夫,在音讯发送时能够进行指定,也反对队列的过期工夫,从音讯入队列开始计算,只有超过了队列的超时工夫配置,那么音讯会主动的革除。

设置队列的话就是整个队列的音讯到时都会过期,设置音讯的话就是单条音讯到时主动过期。

    // TTL 队列示例
    @Bean
    public Queue ttlQueue() {Map<String, Object> arguments = new HashMap<>();
        // 设置 3s 过期
        arguments.put("x-message-ttl",3000);
        return new Queue("topicQueue1",false,false,false, arguments);
    }

下面的代码就是演示如何创立一个 TTL 队列,须要放入参数才行,队列结构中的其余参数我为了不便间接填了 false。

    public void sendTtl() {String message = "Hello 我是作者和耳朵,欢送关注我。" + LocalDateTime.now().toString();

        System.out.println("Message content :" + message);

        // 设置过期 3s
        MessageProperties props = MessagePropertiesBuilder.newInstance()
                .setExpiration("3000").build();

        rabbitTemplate.send(Producer.QUEUE_NAME,new Message(message.getBytes(StandardCharsets.UTF_8),props));
        System.out.println("音讯发送结束。");
    }

设置音讯的 TTL 也是设置参数即可。

以上就是 RabbitMQ 中对于 TTL 的知识点。

4. ????DLX 死信队列

DLX 死信队列 尽管叫队列,但其实指的是 Exchange,或者说指的Exchange 和它所属的Queue,他俩一块形成了死信队列。

当一条音讯:

  • 生产被回绝(basic.reject/basic.nack)并且 requeue=false
  • TTL 过期
  • 要进入的队列达到最大长度

这三种状况,就能够断定一条音讯死了,这种音讯如果咱们没有做解决,它就会被主动删除。

但其实咱们能够在队列上加上一个参数,使当队列中发现了 死亡的音讯 之后会将它主动转发到某个 Exchange,由指定的Exchange 来解决这些死亡的音讯。

这个解决死亡音讯的 Exchange 和之前咱们讲述的 Exchange 没什么区别,仍然能够绑定队列而后进行音讯生产。

    // DLX 队列示例
    @Bean
    public Queue dlxQueue() {Map<String, Object> arguments = new HashMap<>();
        // 指定音讯死亡后发送到 ExchangeName="dlx.exchange" 的交换机去
        arguments.put("x-dead-letter-exchange","dlx.exchange");
        return new Queue("topicQueue1", false, false, false, arguments);
    }

如上代码,就是设置了一个队列中的音讯死亡后的去处,就等于音讯死亡后给它不把它删掉而是做一次转发,发到其余 Exchange 去。

那这样搞有什么用呢?这就取决于业务需要了,不过下一节会用到它,接着往下看~

5. ???? 延时队列

RabbitMQ的基因中没有延时队列这回事,它不能间接指定一个队列类型为延时队列,而后去延时解决,然而通过下面两节的铺垫,咱们能够将 TTL+DLX 相结合,这就能组成一个延时队列。

构想一个场景,下完订单之后 15 分钟未付款咱们就要将订单敞开,这就是一个很经典的演示生产的场景,如果拿 RabbitMQ 来做,咱们就须要联合 TTL+DLX 了。

先把订单音讯设置好 15 分钟过期工夫,而后过期后队列将音讯转发给咱们设置好的 DLX-ExchangeDLX-Exchange 再将分发给它绑定的队列,咱们的消费者再生产这个队列中的音讯,就做到了延时十五分钟生产。

真是 super~~~ 简略呢

后记

收尾了收尾了,RabbitMQ完结了,尽管有些货色没有讲比方:镜像队列,因为我没用过而且个别轮不到本人来做这个,所以就懒了一下就不写这个了,RabbitMQ毕竟不是一个天生的分布式音讯队列,弄镜像什么的还是有点麻烦的。

陆陆续续仿佛写了快一个月呢,货色有点多也有些繁冗,要不下期写一篇文章专门回顾一下,再画个思维导图什么的,给大家梳理一下,再抽几个 小册六折码

最初再给优狐打个广告,最近掘金在 GitHub 下面建设了一个开源打算 – open-source,旨在收录各种好玩的好用的开源库,如果大家有想要自荐或者分享的开源库都能够参加进去,为这个开源打算做一份奉献,同时这个开源库的 Start 也在稳步增长中,参加进去也能够减少本人我的项目的曝光度,两全其美。

同时这个开源库还有一个兄弟我的项目 – open-source-translation,旨在招募技术文章翻译志愿者进行技术文章的翻译工作,
争做最棒开源翻译,翻译业界高质量文稿,为技术人的成长献一份力。


最近这段时间事件挺多,优狐令我八月底之前降级到三级,所以各位读者的赞对我很重要,心愿大家可能高抬贵手,帮我一哈~

好了,以上就是本期的全部内容,感激你能看到这里,欢送对本文点赞珍藏与评论,???? 你们的每个点赞都是我创作的最大能源。

我是耳朵,一个始终想做常识输入的伪文艺程序员,咱们下期见。

本文代码:码云地址 GitHub 地址

正文完
 0