AMQP 和IM的区别

AMQP:

1、可以一对多广播,也可以一对一广播

2、生产者和消费者不知道对方是谁

IM:

1、只能一对一广播

2、生产者和消费者知道对方是谁

RabbitMQ:只是消息代理

  • 我们不生产消息,我们只是消息的搬运工

  • 每条消息只会发送给一个订阅者(一个萝卜一个坑)

消息的传递过程:

生产者==>MQ==>消费者

消息

  • 有效载荷:需要传输的数据内容本身

  • 标签:用来告诉Rabbit消息应该投递给谁

MQ的相关概念

  • 交换器:用于接收生产者发送过来的消息

  • 队列:用来存储生产者发送过来的消息,供消费者消费,可以理解为装消息的容器

  • 绑定:用来决策交换器将消息发送到哪个队列上

如果用乘坐火车打比方,可以这样理解RabbitMQ

乘客是消息,火车站进站安检口相当于交换器,负责接收乘客,并告诉乘客自己应该到哪个检票口等候

检票口排队的乘客相当于队列,乘坐同一班次列车的乘客在同一个检票口检票进站

乘客的手上的火车票相当于绑定(路由键),用来告诉乘客该坐哪一班次的列车,该从哪一个检票口进站。

火车车厢里的每一个座位就相当于消费者,一个座位只能给一个乘客坐

队列

什么是队列?

队列(Queues)是你的消息(messages)的终点,可以理解成装消息的容器。消息就一直在里面,直到有客户端(也就是消费者,Consumer)连接到这个队列并且将其取走为止

队列相关命令:

basic.consume:持续订阅消息,将信道设置为接受模式。消息一到达队列,消费者就接收消息,可以持续接收多条消息

basic.get:订阅单条消息,接收消息后,取消订阅。这样做是为了让消费者只接收下一条消息,如果想获得更多消息,需要再次发送basic.get。

basic.ack:消费者接收消息后,向RabbitMQ发送确认,表示已经收到消息

auto_ack:消费者在订阅队列是如果设置为auto_ack,表示消费者一旦接收消息后,RabbitMQ自动默认为消费者确认收到了消息。

basic.reject:消费者拒绝接收MQ发送过来的消息。RabbitMQ2.0版本后新增的命令

requeue:

true:如果requeue参数设置为true,则RabbitMQ将消息重新发送给下一位消费者

false:如果设置为false,则RabbitMQ将消息从队列移除

queue.declare:创建队列,如果不指定队列名称,则Rabbit会分配一个随机名称,并在命令的响应中返回

exclusive:如果设置为true,列队变为私有的,即一个队列只有一个消费者

aotu-delete:当最后一个消费者取消订阅后,队列会自动移除。如果需要临时创建一个队列,可以结合exclusive使用。消费者断开连接时,队列自动移除

队列工作原理

多个消费者订阅同一队列时,怎么发送消息?

消费者A和B同时订阅了seed_bin队列

1、消息Message_A到达队列seed_bin

2、RabbitMQ把Message_A发送给A

3、A确认接收到了消息Mesage_A

4、RabbitMQ将消息Message_A从队列seed_bin删除

5、消息Message_B到达队列seed_bin

6、RabbitMQ把Message_B发送给B

7、B确认接收到了消息Mesage_B

8、RabbitMQ将消息Message_B从队列seed_bin删除

注意

如果消费者收到一条消息后,从RabbiMQ队列断开了(或者说取消了订阅),一直没有发送确认。那么MQ认为这条消息没有发送,然后会重新将该消息发送给下一位消费者。这样做的好处是如果接收消息的程序出现问题,或者有bug,导致没有发送确认,这样RabbitMQ不会再给该应用发送消息。因为RabbitMQ会认为你的程序还没有准备好接收下一条消息,这样可以防止消息源源不断的涌向你的应用,到导致过载。

交换器

什么是交换器?

交换器是服务器接收到生产者发送过来的消息后,根据不同的规则,将消息投递到不同的队列的工具。这些规则被称为路由键。队列是通过路由键绑定到交换器的。当生产者将消息发给RabbitMQ代理服务器时,消息将拥有一个路由键,Rabbit会将其与绑定的路由键践行匹配,如果匹配则投递到该队列,如果匹配不到任何绑定模式,则消息进入黑洞。

交换器的类型

  • direct:如果路由键匹配,则直接投递到对应的队列

  • fanout:不处理路由键,向所有与之绑定的队列投递消息

  • topic:处理路由键,按模式匹配,向符合规则的队列投递消息

  • headers:允许匹配消息的header,而非路由键,除此之外,direct完全一致,但性能差很多,基本不用了。

direct:

处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。这是一个完整的匹配。如果一个队列绑定到该交换机上要求路由键 “dog”,则只有被标记为“dog”的消息才被转发,不会转发dog.puppy,也不会转发dog.guard,只会转发dog

fanout:

不处理路由键。你只需要简单的将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。Fanout交换机转发消息是最快的。

topic:

将路由键和某模式进行匹配。此时队列需要绑定要一个模式上。符号“#”匹配一个或多个词,符号“*”匹配不多不少一个词。因此“audit.#”能够匹配到“audit.irs.corporate”,但是“audit.*” 只会匹配到“audit.irs”。请参考下图

虚拟主机

每一个RabbitMQ都能创建虚拟消息服务器,我们称之为虚拟主机(vhost)。

每一个vhost本质上是一个mini版的RabbitMQ服务器,拥有自己的队列、交换器、绑定。更重要的是他们拥有自己的权限机制。这使得你能够安全的使用一个RabbitMQ服务器来服务于众多应用。vhost之于RabbitMQ就像虚拟机之于物理服务器一样。

用户只能在虚拟主机的粒度进行权限控制。因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机。每一个RabbitMQ服务器都有一个默认的虚拟主机“/”。默认的账号密码都为guest,为了安全起见,应该改掉。

注意:在RabbitMQ上创建vhost时,整个集群都会创建该vhost。

如何创建vhost?

1
rabbitmqctl add_vhost [vhost_name]

如何删除vhost?

1
rabbitmqctl delete_vhost [vhost_name]

如何查看服务器上运行的vhost?

1
rabbitmqctl list_vhosts

如何管理远程的RabbitMQ节点?

1
rabbitmqctl -n rabbit@server_name

server_name可以是IP地址

持久化

默认情况下,当RabbitMQ服务器重启后,那些队列和交换器就都会消失。原因在于每个队列和交换器的druable属性。该属性默认情况下为false,它决定了RabbitMQ是否需要在崩溃或者重启后重新创建队列。将它设置为true,就不需要再服务器重启后重新创建队列和交换器了。

如果你以为只需要将队列和交换器的durable属性设置为true,就可以让消息幸免于重启就错了,能从AMQP中恢复崩溃的消息,我们称之为持久化。在消息发布前,通过把它的“Delivery Mode”(投递模式)设置为2,也就是持久的(persistent)即可。

注意:将投递模式设置为2,仅仅表示消息被标识为持久化的,它还必须被发布到持久化的交换器,并投递都持久化的队列中才行。否则,包含持久化的队列和交换器会在RabbitMQ重启后小时,而消息变成孤儿。因此,实现持久化必须:

  • 1.    将交换机设成 durable。

  • 2.    将队列设成 durable。

  • 3.    将消息的 Delivery Mode 设置成2

交换器和队列可以设置为durable,那绑定(Bindings)怎么办?我们无法在创建绑定的时候设置成durable。没问题,如果你绑定了一个durable的队列和一个durable的交换机,RabbitMQ会自动保留这个绑定。类似的,如果删除了某个队列或交换机(无论是不是durable),依赖它的绑定都会自动删除。

注意两点:

  • RabbitMQ 不允许你绑定一个非坚固(non-durable)的交换机和一个durable的队列。反之亦然。要想成功必须队列和交换机都是durable的。

  • 一旦创建了队列和交换机,就不能修改其标志了。例如,如果创建了一个non-durable的队列,然后想把它改变成durable的,唯一的办法就是删除这个队列然后重现创建。因此,最好仔细检查创建的标志。

RabbitMQ持久化的机制

RabbitMQ能确保持久性消息能够在服务器重启后恢复的方式是,将消息写入磁盘上的一个持久性的日志文件中。当发布一条持久性消息到持久化交换器上时,Rabbit会先将消息发送到持久化日志文件,然后再发送到持久化交换器。如果说这条消息路由到非持久化的队列上,它会自动从持久性日志中移除,重启后无法恢复。

性能

对于一个需要在重启之后恢复的消息来说,它需要被写入到磁盘上,这样性能就会大打折扣。写入磁盘要比写入内存慢的不止一点点,而且会极大的减少RabbitMQ服务器每秒可以处理的消息数。另外,持久消息在RabbitMQ内建集群环境下工作得并不好。RabbitMQ集群的任何一个节点上都没有备份的拷贝,这意味着运行某一队列的集群节点崩溃了,在该节点恢复之前,这个队列也就从集群队列中消失了。

事务/confirm模式

RabbitMQ使用事务会降低大约2~10倍的消息吞吐量,几乎吸干了RabbitMQ的性能。后来RabbitMQ团队拿出了更好的加爵方案==>“发送方确认模式”(confirm)。需要将RabbitMQ信道设置为confirm模式,并且一旦设置成为confirm模式后,必须通过重新创建信道来关闭该设置。


confirm模式工作机制

一旦信道进入confirm模式,所有信道上发布的消息都会被指派一个唯一的ID号(从1开始)。一旦消息被投递给所有匹配的的队列后,信道会发送一个发送方确认模式给生产者(包含消息的ID),这样生产者就知道消息被安全送到目标队列了。如果消息和队列是可持久化的,那么确认消息只会在队列将消息写入磁盘后才会发出。发送方确认模式的最大好处是异步的。一旦发布了消息,生产者可以在等待确认的同时继续发送下一条消息。当确认消息最终收到的时候,生产者应用程序的回调方法就会被触发来处理该确认消息。如果RabbitMQ发生了内部错误从而导致消息丢失,Rabbit会发送一条nack(not acknowledge,未确认)消息。就像发送确认消息那样,只不过这次明确说明消息已经丢失。由于没有事务回滚的概念,因此发送方确认模式更加轻量级,同时,对RabbitMQ代理服务器的性能几乎可以忽略不计。

本文转自 曾哥最爱 51CTO博客,原文链接:http://blog.51cto.com/zengestudy/1874402,如需转载请自行联系原作者

RabbitMQ基本概念相关推荐

  1. RabbitMQ 基本概念与高级特性

    文章目录 1. 什么是消息队列 1.1 消息队列概述 1.2 使用消息队列的优势 1.3 使用消息队列的劣势 1.4 常见的消息队列产品对比 2. RabbitMQ 基本概念 2.1 RabbitMQ ...

  2. RabbitMQ 幂等性概念及业界主流解决方案

    RabbitMQ 幂等性概念及业界主流解决方案 参考文章: (1)RabbitMQ 幂等性概念及业界主流解决方案 (2)https://www.cnblogs.com/shoshana-kong/p/ ...

  3. java B2B2C Springcloud电子商务平台源码-RabbitMQ基础概念...

    RabbitMQ是一个由erlang开发的AMQP的开源实现. 需要JAVA Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码 一零三八七七四六二六 AMQP,即Adva ...

  4. RabbitMQ核心概念及基础API应用

    RabbitMQ核心概念及基础API应用 1 主流中间件介绍 衡量消息中间件的指标:服务性能,数据存储,集群架构. 1.ActiveMQ:Apache,支持JMS规范最完整的. 2.RocketMQ ...

  5. (2)RabbitMQ基础概念及工作流程详解

    上一节中我们对MQ做了一个概要介绍,这一节开始我们选取RabbitMQ开始进行学习,本节将会RabbitMQ做个简单介绍,并且会对其常见的基础概念做个讲解,最后会简单介绍一下RabbitMQ的工作流程 ...

  6. RabbitMQ核心概念

    AMQP的四个主要概念 1.虚拟主机(virtual host)或(vhost) 2.交换机(exchange) 3.队列(queue) 4.绑定器(bind) 什么是虚拟主机? 一组交换机.队列和绑 ...

  7. RabbitMQ基础概念详细介绍

    转至:http://www.ostest.cn/archives/497 引言 你是否遇到过两个(多个)系统间需要通过定时任务来同步某些数据?你是否在为异构系统的不同进程间相互调用.通讯的问题而苦恼. ...

  8. SpringBoot高级消-息-RabbitMQ基本概念简介

    首先对RabbitMQ做一个简单的介绍,和快速入门,RabbitMQ是我们的AMQP,就是我们高级消息队列的一个实现产品,他的稳定性和可靠性呢非常高,也是我们现在一个非常流行的一个消息中间件,那么我们 ...

  9. RabbitMQ基础概念详解

    欢迎支持笔者新作:<深入理解Kafka:核心设计与实践原理>和<RabbitMQ实战指南>,同时欢迎关注笔者的微信公众号:朱小厮的博客. RabbitMQ简介 AMQP,即Ad ...

最新文章

  1. Windows Server 2012体验之卸载辅助域控制器
  2. Getting Contexts 获得上下文
  3. java虚拟机深入理解Java虚拟机:JVM高级特性与最佳实践(第2版)
  4. UVa 12333 - Revenge of Fibonacci manweifc(模拟加法竖式 字典树)
  5. c语言程序设计教程周新答案,c语言程序设计教程周新答案
  6. TCP/IP详解 卷1:协议—概述
  7. 湖南省长沙市谷歌高清卫星地图下载
  8. 《博弈论》— 人生何处不博弈
  9. Unity 源码研究 获取颜色面板ColorPicker键值信息
  10. android 自定义桌面,无需 root,3 个 App 帮你构建高效的 Android 桌面
  11. 亲身体验:八款知名虚拟主机对比测评
  12. 西瓜玲子5.20打卡日记
  13. RISC-V 架构指令集手册 第一册 无特权指令集 中文翻译
  14. 我命由我不由天,我的UI我做主「定制Spring Boot Admin UI的页面」- 第298篇
  15. 全球No.1集装箱人工智能企业中国上海人工智能领军企业CIMC中集飞瞳,已完成百万AI集装箱箱况残损检验识别,上亿集装箱信息识别
  16. Android zxing扫描本地二维码图片NotFoundException
  17. 如何在公众号文章中添加申请表(Word文档)
  18. 使用小程序做交互的技巧(演讲内容实录)丨掘金开发者大会
  19. mysql数据库主备表校验与修复
  20. JAVA 修饰符笔记

热门文章

  1. java 三角依次递增在递减_java中用for循环怎样打印三角行啊,主要是不理解什么情况外层循环递增什么时候递减,如等腰三角形...
  2. android 请求参数打印,android retrofit 请求参数格式RequestBody的方法
  3. 安阳工学院计算机二级成绩查询,2008年下半年计算机等级考试成绩可以查询了?...
  4. php登录注册demo,PHP实现登录功能DEMO
  5. python手机代码识别数字_python实现kNN算法识别手写体数字的示例代码
  6. 吴恩达机器学习笔记:(二)代价函数
  7. 【生成模型】极大似然估计,你必须掌握的概率模型
  8. 【完结】12篇文章告诉你深度学习理论应该学到什么水平
  9. 全球及中国家用除湿机行业消费需求调研及十四五发展趋势研究报告2022-2027年
  10. 全球及中国不锈钢商用厨刀行业营销战略及未来发展趋势分析报告2022年版