人生终将是场单人旅途,孤单之前是迷茫,孤单过后是成长。
楔子
本篇是音讯队列 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-Exchange
,DLX-Exchange
再将分发给它绑定的队列,咱们的消费者再生产这个队列中的音讯,就做到了延时十五分钟生产。
真是 super~~~ 简略呢
后记
收尾了收尾了,RabbitMQ
完结了,尽管有些货色没有讲比方:镜像队列,因为我没用过而且个别轮不到本人来做这个,所以就懒了一下就不写这个了,RabbitMQ
毕竟不是一个天生的分布式音讯队列,弄镜像什么的还是有点麻烦的。
陆陆续续仿佛写了快一个月呢,货色有点多也有些繁冗,要不下期写一篇文章专门回顾一下,再画个思维导图什么的,给大家梳理一下,再抽几个 小册六折码
。
最初再给优狐打个广告,最近掘金在 GitHub 下面建设了一个开源打算 – open-source,旨在收录各种好玩的好用的开源库,如果大家有想要自荐或者分享的开源库都能够参加进去,为这个开源打算做一份奉献,同时这个开源库的 Start
也在稳步增长中,参加进去也能够减少本人我的项目的曝光度,两全其美。
同时这个开源库还有一个兄弟我的项目 – open-source-translation,旨在招募技术文章翻译志愿者进行技术文章的翻译工作,
争做最棒开源翻译,翻译业界高质量文稿,为技术人的成长献一份力。
最近这段时间事件挺多,优狐令我八月底之前降级到三级,所以各位读者的赞对我很重要,心愿大家可能高抬贵手,帮我一哈~
好了,以上就是本期的全部内容,感激你能看到这里,欢送对本文点赞珍藏与评论,???? 你们的每个点赞都是我创作的最大能源。
我是耳朵,一个始终想做常识输入的伪文艺程序员,咱们下期见。
本文代码:码云地址 GitHub 地址