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

楔子

本篇是消息队列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地址

RabbitMQ高级之消息限流与延时队列的更多相关文章

  1. Rabbitmq——实现消费端限流 --NACK重回队列

    如果是高并发下,rabbitmq服务器上收到成千上万条消息,那么当打开消费端时,这些消息必定喷涌而来,导致消费端消费不过来甚至挂掉都有可能. 在非自动确认的模式下,可以采用限流模式,rabbitmq ...

  2. Rabbitmq之高级特性——实现消费端限流&NACK重回队列

    如果是高并发下,rabbitmq服务器上收到成千上万条消息,那么当打开消费端时,这些消息必定喷涌而来,导致消费端消费不过来甚至挂掉都有可能. 在非自动确认的模式下,可以采用限流模式,rabbitmq ...

  3. 使用rabbitmq手动确认消息的,定时获取队列消息实现

    描述问题 最近项目中因为有些数据,需要推送到第三方系统中,因为数据会一直增加,并且需要与第三方系统做相关交互. 相关业务 本着不影响线上运行效率的思想,我们将增加的消息放入rabbitmq,使用另一个 ...

  4. RabbitMQ高级之如何保证消息可靠性?

    人生终将是场单人旅途,孤独之前是迷茫,孤独过后是成长. 楔子 本篇是消息队列RabbitMQ的第四弹. RabbitMQ我已经写了三篇了,基础的收发消息和基础的概念我都已经写了,学任何东西都是这样,先 ...

  5. 基于Redis实现延时队列服务

    背景 在业务发展过程中,会出现一些需要延时处理的场景,比如: a.订单下单之后超过30分钟用户未支付,需要取消订单 b.订单一些评论,如果48h用户未对商家评论,系统会自动产生一条默认评论 c.点我达 ...

  6. 【转】基于Redis实现延时队列服务

    背景 在业务发展过程中,会出现一些需要延时处理的场景,比如: a.订单下单之后超过30分钟用户未支付,需要取消订单b.订单一些评论,如果48h用户未对商家评论,系统会自动产生一条默认评论c.点我达订单 ...

  7. 微服务-springboot-rabbitmq:实现延时队列

    延时队列应用于什么场景 延时队列顾名思义,即放置在该队列里面的消息是不需要立即消费的,而是等待一段时间之后取出消费.那么,为什么需要延迟消费呢?我们来看以下的场景 网上商城下订单后30分钟后没有完成支 ...

  8. SpringBoot 整合 RabbitMQ(包含三种消息确认机制以及消费端限流)

    目录 说明 生产端 消费端 说明 本文 SpringBoot 与 RabbitMQ 进行整合的时候,包含了三种消息的确认模式,如果查询详细的确认模式设置,请阅读:RabbitMQ的三种消息确认模式 同 ...

  9. 面试官:RabbitMQ怎么实现消费端限流

    哈喽!大家好,我是小奇,一位不靠谱的程序员 小奇打算以轻松幽默的对话方式来分享一些技术,如果你觉得通过小奇的文章学到了东西,那就给小奇一个赞吧 文章持续更新 一.前言 RabbitMQ有很多高级特性, ...

随机推荐

  1. Linux 如何以管理员身份运行终端

    如何以管理员身份在终端执行指令: 目录 如何以管理员身份在终端执行指令: 1. 以sudo 指令在其他指令前加上sudo 2. 以su 进入root权限,以管理员方式执行命令 设置root初始密码: ...

  2. 【六省联考2017】组合数问题 题解(矩阵快速幂优化DP)

    题目链接 题目大意:求$(\sum\limits_{i=0}^n C_{nk}^{ik+r})\ mod \ p$的值. --------------------- 讲真,一开始看到这个题我都没往DP ...

  3. TF签名为什么这么稳定?TF签名找微导流!

      TF签名作为目前最稳定的签名方式收到了业界开发者们的认可,而在如今鱼龙混杂的签名平台中,应该如何选择客厅的TF签名平台呢?下面就一起来看看TF签名为什么这么稳定?TF签名找微导流!   TF签名的 ...

  4. Azure Load Balancer(二) 基于内部的负载均衡来转发为访问请求

    一,引言 上一节,我们使用 Azure Load Balancer 类型为外部的,来转发我们的 Web 服务.今天我们看看另一种类型为 “Internal” 的 Azure Load Balancer ...

  5. Pytorch_第七篇_深度学习 (DeepLearning) 基础 [3]---梯度下降

    深度学习 (DeepLearning) 基础 [3]---梯度下降法 Introduce 在上一篇"深度学习 (DeepLearning) 基础 [2]---神经网络常用的损失函数" ...

  6. 聊聊WindowServer那些事!

    前言说明 使用工具:VS2019 思考为什么要使用WindowServer,它能做什么了?(后面解答) 一:什么是WindowServer?(我们做的是一个什么东西?)         Microso ...

  7. 基于Python的AT命令测试脚本

    对于各种有线&无线调制解调器(modem)产品来说,AT命令是事实上的标准接口之一,在工业界被广泛使用. 我开发了一套基于Python的AT命令测试脚本,源代码可在github上获取: htt ...

  8. Web 开发必须掌握的三个技术:Token、Cookie、Session

    在Web应用中,HTTP请求是无状态的.即:用户第一次发起请求,与服务器建立连接并登录成功后,为了避免每次打开一个页面都需要登录一下,就出现了cookie,Session. Cookie Cookie ...

  9. (数据科学学习手札92)利用query()与eval()优化pandas代码

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 利用pandas进行数据分析的过程,不仅仅是计算 ...

  10. 笑了,面试官问我知不知道异步编程的Future。

    荒腔走板 大家好,我是 why,欢迎来到我连续周更优质原创文章的第 60 篇. 老规矩,先来一个简短的荒腔走板,给冰冷的技术文注入一丝色彩. 上面这图是我五年前,在学校宿舍拍的. 前几天由于有点事情, ...