RabbitMQ 基础

三个核心概念

Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast)
Queue:消息最终被送到这里等待 consumer 取走
Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到exchange中的查询表中,用于message的分发依据

RabbitMQ的工作模式!

Work queues 工作队列模式

Work Queues:与入门程序的简单模式相比,多了一个或一些消费端,多个消费端共同消费同一个队列中的消息。
应用场景:对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度。

  1. 在一个队列中如果有多个消费者,那么消费者之间对于同一个消息的关系是竞争的关系。
  2. Work Queues 对于任务过重或任务较多情况使用工作队列可以提高任务处理的速度。例如:短信服务部署多个,只需要有一个节点成功发送即可。

Pub/Sub 订阅模式 也可以叫做topic广播模式 fanout

在订阅模型中,多了一个 Exchange 角色,而且过程略有变化:
P:生产者,也就是要发送消息的程序,但是不再发送到队列中,而是发给X(交换机)
C:消费者,消息的接收者,会一直等待消息到来
Queue:消息队列,接收消息、缓存消息
Exchange:交换机(X)。一方面,接收生产者发送的消息。另一方面,知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange有常见以下3种类型:
Fanout:广播,将消息交给所有绑定到交换机的队列
Direct:定向,把消息交给符合指定routing key 的队列
Topic:通配符,把消息交给符合routing pattern(路由模式) 的队列
Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与 Exchange 绑定,或者没有符合路由规则的队列,那么消息会丢失!

  1. 交换机需要与队列进行绑定,绑定之后;一个消息可以被多个消费者都收到。
  2. 发布订阅模式与工作队列模式的区别:
    工作队列模式不用定义交换机,而发布/订阅模式需要定义交换机
    发布/订阅模式的生产方是面向交换机发送消息,工作队列模式的生产方是面向队列发送消息(底层使用默认交换机)
    发布/订阅模式需要设置队列和交换机的绑定,工作队列模式不需要设置,实际上工作队列模式会将队列绑 定到默认的交换机

3 Routing 路由模式

队列与交换机的绑定,不能是任意绑定了,而是要指定一个 RoutingKey(路由key)
消息的发送方在向 Exchange 发送消息时,也必须指定消息的 RoutingKey
Exchange 不再把消息交给每一个绑定的队列,而是根据消息的 Routing Key 进行判断,只有队列的Routingkey 与消息的 Routing key 完全一致,才会接收到消息

P:生产者,向 Exchange 发送消息,发送消息时,会指定一个routing key
X:Exchange(交换机),接收生产者的消息,然后把消息递交给与 routing key 完全匹配的队列
C1:消费者,其所在队列指定了需要 routing key 为 error 的消息
C2:消费者,其所在队列指定了需要 routing key 为 info、error、warning 的消息

Routing 模式要求队列在绑定交换机时要指定 routing key,消息会转发到符合 routing key 的队列。

4 Topics 通配符模式

红色 Queue:绑定的是 usa.# ,因此凡是以 usa. 开头的 routing key 都会被匹配到
黄色 Queue:绑定的是 #.news ,因此凡是以 .news 结尾的 routing key 都会被匹配

Topic 类型与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。只不过 Topic 类型Exchange 可以让队列在绑定 Routing key 的时候使用通配符!
Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
通配符规则:# 匹配一个或多个词,* 匹配不多不少恰好1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert,item.* 只能匹配 item.insert

Topic 主题模式可以实现 Pub/Sub 发布与订阅模式和 Routing 路由模式的功能,只是 Topic 在配置routing key 的时候可以使用通配符,显得更加灵活。

RabbitMQ 高级特性

消息的可靠投递

在使用 RabbitMQ 的时候,作为消息发送方希望杜绝任何消息丢失或者投递失败场景。RabbitMQ 为我们提供了两种方式用来控制消息的投递可靠性模式。
confirm 确认模式
return 退回模式

rabbitmq 整个消息投递的路径为:
producer—>rabbitmq broker—>exchange—>queue—>consumer
消息从 producer 到 exchange 则会返回一个 confirmCallback 。
消息从 exchange–>queue 投递失败则会返回一个 returnCallback 。
我们将利用这两个 callback 控制消息的可靠性投递

设置ConnectionFactory的publisher-confirms=“true” 开启 确认模式。
使用rabbitTemplate.setConfirmCallback设置回调函数。当消息发送到exchange后回调confirm方法。在方法中判断ack,如果为true,则发送成功,如果为false,则发送失败,需要处理。
设置ConnectionFactory的publisher-returns=“true” 开启 退回模式。
使用rabbitTemplate.setReturnCallback设置退回函数,当消息从exchange路由到queue失败后,如果设置了rabbitTemplate.setMandatory(true)参数,则会将消息退回给producer。并执行回调函数returnedMessage。

在RabbitMQ中也提供了事务机制,但是性能较差,此处不做讲解。
使用channel下列方法,完成事务控制:
txSelect(), 用于将当前channel设置成transaction模式
txCommit(),用于提交事务
txRollback(),用于回滚事务

Consumer Ack 消息的可靠性签收

ack指Acknowledge,确认。 表示消费端收到消息后的确认方式。
有三种确认方式:
自动确认:acknowledge=“none”
手动确认:acknowledge=“manual”
根据异常情况确认:acknowledge=“auto”,(这种方式使用麻烦,不作讲解)

其中自动确认是指,当消息一旦被Consumer接收到,则自动确认收到,并将相应 message 从 RabbitMQ 的消息缓存中移除。
但是在实际业务处理中,很可能消息接收到,业务处理出现异常,那么该消息就会丢失。如果设置了手动确认方式,则需要在业务处理成功后,
调用channel.basicAck(),手动签收,如果出现异常,则调用channel.basicNack()方法,让其自动重新发送消息。

在rabbit:listener-container标签中设置acknowledge属性,设置ack方式 none:自动确认,manual:手动确认

如果在消费端没有出现异常,则调用channel.basicAck(deliveryTag,false);方法确认签收消息

如果出现异常,则在catch中调用 basicNack或 basicReject,拒绝消息,让MQ重新发送消息。

消费端限流

在rabbit:listener-container 中配置 prefetch属性设置消费端一次拉取多少消息

消费端的确认模式一定为手动确认。acknowledge=“manual”

TTL

TTL 全称 Time To Live(存活时间/过期时间)。
当消息到达存活时间后,还没有被消费,会被自动清除。
RabbitMQ可以对消息设置过期时间,也可以对整个队列(Queue)设置过期时间。

设置队列过期时间使用参数:x-message-ttl,单位:ms(毫秒),会对整个队列消息统一过期。
设置消息过期时间使用参数:expiration。单位:ms(毫秒),当该消息在队列头部时(消费时),会单独判断这一消息是否过期。
如果两者都进行了设置,以时间短的为准。

死信队列

死信队列,英文缩写:DLX 。Dead Letter Exchange(死信交换机),当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。
消息成为死信的三种情况:

  1. 队列消息长度到达限制;

  2. 消费者拒接消费消息,basicNack/basicReject,并且不把消息重新放入原目标队列,requeue=false;

  3. 原队列存在消息过期设置,消息到达超时时间未被消费;

  4. 死信交换机和死信队列和普通的没有区别

  5. 当消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列

  6. 消息成为死信的三种情况:

  7. 队列消息长度到达限制;

  8. 消费者拒接消费消息,并且不重回队列;

  9. 原队列存在消息过期设置,消息到达超时时间未被消费;

死信队列,英文缩写:DLX  。Dead Letter Exchange(死信交换机),当消息成为Dead message后,可以被重新发送到另一个交换机,这个交换机就是DLX。
消息成为死信的三种情况:
1. 队列消息长度到达限制;
2. 消费者拒接消费消息,basicNack/basicReject,并且不把消息重新放入原目标队列,requeue=false;
3. 原队列存在消息过期设置,消息到达超时时间未被消费;1. 死信交换机和死信队列和普通的没有区别2. 当消息成为死信后,如果该队列绑定了死信交换机,则消息会被死信交换机重新路由到死信队列3. 消息成为死信的三种情况:
1. 队列消息长度到达限制;
2. 消费者拒接消费消息,并且不重回队列;
3. 原队列存在消息过期设置,消息到达超时时间未被消费;<!--死信队列:1. 声明正常的队列(test_queue_dlx)和交换机(test_exchange_dlx)2. 声明死信队列(queue_dlx)和死信交换机(exchange_dlx)3. 正常队列绑定死信交换机设置两个参数:* x-dead-letter-exchange:死信交换机名称* x-dead-letter-routing-key:发送给死信交换机的routingkey--><!--1. 声明正常的队列(test_queue_dlx)和交换机(test_exchange_dlx)--><rabbit:queue name="test_queue_dlx" id="test_queue_dlx"><!--3. 正常队列绑定死信交换机--><rabbit:queue-arguments><!--3.1 x-dead-letter-exchange:死信交换机名称--><entry key="x-dead-letter-exchange" value="exchange_dlx" /><!--3.2 x-dead-letter-routing-key:发送给死信交换机的routingkey--><entry key="x-dead-letter-routing-key" value="dlx.hehe" /><!--4.1 设置队列的过期时间 ttl--><entry key="x-message-ttl" value="10000" value-type="java.lang.Integer" /><!--4.2 设置队列的长度限制 max-length --><entry key="x-max-length" value="10" value-type="java.lang.Integer" /></rabbit:queue-arguments></rabbit:queue><rabbit:topic-exchange name="test_exchange_dlx"><rabbit:bindings><rabbit:binding pattern="test.dlx.#" queue="test_queue_dlx"></rabbit:binding></rabbit:bindings></rabbit:topic-exchange><!--2. 声明死信队列(queue_dlx)和死信交换机(exchange_dlx)
--><rabbit:queue name="queue_dlx" id="queue_dlx"></rabbit:queue><rabbit:topic-exchange name="exchange_dlx"><rabbit:bindings><rabbit:binding pattern="dlx.#" queue="queue_dlx"></rabbit:binding></rabbit:bindings></rabbit:topic-exchange>

6 延迟队列

延迟队列,即消息进入队列后不会立即被消费,只有到达指定时间后,才会被消费。
需求:
1. 下单后,30分钟未支付,取消订单,回滚库存。
2. 新用户注册成功7天后,发送短信问候。
实现方式:
3. 定时器
4. 延迟队列5. 延迟队列 指消息进入队列后,可以被延迟一定时间,再进行消费。6. RabbitMQ没有提供延迟队列功能,但是可以使用 : TTL + DLX 来实现延迟队列效果。



RabbitMQ 正确使用姿势相关推荐

  1. java 日志使用_Java日志正确使用姿势

    前言 关于日志,在大家的印象中都是比较简单的,只须引入了相关依赖包,剩下的事情就是在项目中"尽情"的打印我们需要的信息了.但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的 ...

  2. java 同步 异步 阻塞 非阻塞_Java日志正确使用姿势,大白话搞懂什么是同步/异步/阻塞/非阻塞...

    前言 关于日志,在大家的印象中都是比较简单的,只须引入了相关依赖包,剩下的事情就是在项目中"尽情"的打印我们需要的信息了.但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的 ...

  3. Java日志正确使用姿势

    前言 关于日志,在大家的印象中都是比较简单的,只须引入了相关依赖包,剩下的事情就是在项目中"尽情"的打印我们需要的信息了.但是往往越简单的东西越容易让我们忽视,从而导致一些不该有的 ...

  4. 论机器学习的正确学习姿势

    论机器学习的正确学习姿势 策划 | 刘燕作者 | Caleb Kaiser翻译 | Sambodhi编辑 | Linda很多开发人员并没有机器学习领域的背景,在机器学习如火如荼的今天,没学过机器学习的 ...

  5. 什么叫取反_转载:CodeReview正确的姿势是什么?

    作者:微博是阿里孤尽 链接:https://www.zhihu.com/question/383079175/answer/1109655276 来源:知乎 著作权归作者所有.商业转载请联系作者获得授 ...

  6. class ts 扩展方法_ts类型声明文件的正确使用姿势

    ts类型声明文件的正确使用姿势 ts声明文件类型 npm install @types/jquery --save-dev 与npm一同发布 解释: package.json 中有 types 字段, ...

  7. java同步锁如何使用_java 同步锁(synchronized)的正确使用姿势

    关于线程安全,线程锁我们经常会用到,但你的使用姿势正确不,反正我用错了好长一段时间而不自知.所以有了这篇博客总结下线程锁的正确打开姿势 废话不说看例子 一,对整个方法进行加锁 1,对整个方法进行加锁, ...

  8. 直播预告|中台基石腾讯云TStack的正确使用姿势

    各位亲爱的小伙伴们,你们好啊~~ 他二哥技术直播又和大家见面了! 还记得在第一期的节目中,Sandy小姐姐和两位技术哥哥带我们见识了腾讯自研交换机的强大实力. (赶紧戳链接复习☝) 这次直播,他二哥邀 ...

  9. MongoDB系列:五、MongoDB Driver使用正确的姿势连接复制集

    MongoDB复制集(Replica Set)通过存储多份数据副本来保证数据的高可靠,通过自动的主备切换机制来保证服务的高可用.但需要注意的时,连接副本集的姿势如果不对,服务高可用将不复存在. 使用复 ...

最新文章

  1. linux sntp 代码,C语言window(linux)平台的SNTP实现
  2. 单载波调制和OFDM调制比较
  3. 算法分析与设计-实验二 动态规划算法设计
  4. ulp通信_Java Math类ulp()方法及示例
  5. php js记住密码功能,jquery.cookie.js实现用户登录保存密码功能的方法_jquery
  6. django model中的DateField()转为时间戳
  7. FreeRTOS 教程指南 学习笔记 第三章 任务管理(二)
  8. Visio帮你轻松画出3D效果示意图
  9. arch Android模拟器,安卓系统上的全能模拟器Retroarch
  10. Ubuntu 中文目录改为英文目录
  11. c语言二维数组学习,C语言学习之二维数组的传参
  12. Unity:简单的蓄力技能的逻辑实现
  13. 继电器在交流应用时的zero-crossing
  14. 《一封来自姐姐的信》
  15. SSM 框架原理简介及解析
  16. 百度文库如何申请个人认证?需要什么资质?
  17. box-shadow四个边框设置阴影样式
  18. 计算机防火墙打不开0x6d9,win7防火墙出现0x6d9该怎么办
  19. 【数据可视化】使用pyecharts制作词云
  20. Java编码规范十大军规

热门文章

  1. 辉涩笔记003—20200529
  2. unity界面介绍及导入模型
  3. python getopterror_python getopt
  4. 欢简述常见的语言表示模型(词嵌入、句表示、篇章表示)
  5. 高级威胁:Ramsay恶意软件针对隔离网络的攻击技术分析
  6. linux fedora 内核,Fedora下使用yum更新Linux内核
  7. 一个IO口控制多个按键方法
  8. ss 计算机视觉啥意思(ss什么意思)
  9. 如何转换图片格式?教你一键快速转格式的方法
  10. cpu风扇转速调节怎么调?怎么查看CPU风扇的转速?所有的CPU风扇都可以调节风扇转速吗,怎么控制?...