人生终将是场单人旅途,孤单之前是迷茫,孤单过后是成长。
楔子
本篇是音讯队列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地址