认识一下 RabbitMQ
分布式系统中,如何在各个应用之间高效的进行通信,是系统设计中的一个关键。
使用 消息代理(message broker) 是一个优雅的解决方案。
RabbitMQ 就是一个被广泛应用的消息代理,遵循 AMQP协议。
接下来我们就了解一下:
- Message Broker 概念
- AMQP 协议的核心构成
- 消息转发的 4 种模式
1. Message Broker
broker 是经纪人的意思,促成卖方、买方的交易,例如房产经纪人。
消息模型中,有消息的生产者、消费者,就相当于卖方、买方。
所以,也需要一个消息经纪人,这就引出了 message broker 的概念。

message broker 从生产者接收消息,再发送给消费者,这样,生产者、消费者可以完全隔离。
RabbitMQ 就是一个 message broker。
2. AMQP
具体如何传递消息?要看使用的消息协议。
RabbitMQ 支持多种协议,其中最重要的是 AMQP(Advanced Message Queuing Protocol)。
AMQP 的概念模型很简单,包含3个部分:
- Queue
- Binding
- Exchange
当一个消息发布到 RabbitMQ 后,首先到达 Exchange,然后 Exchange 把消息分配给 Queue,消费者从 Queue 中得到消息。

AMQP 是一个可编程的协议,我们可以自由配置 exchange, binding, queue。
2.1 Queue 队列
Queue 是先进先出数据结构。
Queue 是 RabbitMQ 存储消息的地方。
Queue 可以灵活的配置,例如:
- 设置 name
- 配置可靠模式,即使 broker 宕机也可以保障数据安全
- 消息自动删除
- 独占模式
- ……
2.3 Consumer 消费者
一个 queue 可以同时连接多个 consumer。
consumer 既可以自己从 queue 拉取消息,也可以由 queue 主动把消息推给 consumer。
2.4 Binding 绑定
Binding 是 Queue 与 Exchange 建立连接的规则。
每个 Queue 都会与一个默认 Exchange 连接,我们可以为这个 Queue 连接更多的 Exchange。
Exchange 通过 Binding 规则,把消息路由到相应的 Queue。
2.5 Exchange
Exchange 是 RabbitMQ 的消息网关。
Exchange 就像是一个接线员,收到消息后决定如何转发。
主要有 4 种转发类型:
- Direct
- Fanout
- Topic
- Header
下面具体了解一下。
3. 消息转发模式
3.1 Direct 直传
Routing key == Binding key
routing key是消息的一个属性。binding key是绑定 queue 与 exchange 时指定的。

生产者(绿色球)发送了一个消息,带着一个 routing key -- img.resize。
当消息到达 exchange(桔色球)后,exchange 会查找所有带着 img.resize 这个 Binding key 的 queue。
找到匹配的 queue 之后,消息就会被发送给这些 queue。
如果没找到,消息会被退回给生产者,或者丢弃。
消息到达指定的 queue 之后,会以轮询的形式分派给消费者(resizer.1/resizer.2),确保负载均衡。
3.2 Fanout 扇形

此方式会忽略 routing key,把消息分派给所有连接的 queue。
最常见的场景就是消息广播。
注意,此方式是 exchange 广播给 queue,不是 queue 广播给 consumer。queue 到 consumer 还是轮询的方式。
3.3 Topic 主题
routing key 与 binding key 进行模式匹配。
Routing key == Pattern in binding key
RabbitMQ 使用 * 和 # 这2个通配符。
* - 匹配一个词。
# - 匹配 0 个或多个词。

routing key 为 logs.error 的消息,匹配 binding key -- logs.error 和 logs.*,所以消息会进入 "only error" 和 "alllogs"。

routing key 为 logs.success 的消息,匹配binding key -- #success 和 logs.*,所以消息会进入 "only success" 和 "alllogs"。
这种形式有非常多的应用场景,可以用于发布-订阅模式、将相关数据分发给期望的 worker 等等。
3.4 Header
一种特殊类型的 exchange,基于消息头中的 key 进行路由。
使用这种方式后,就会忽略消息的 routing key 属性。
对一个 header exchange 创建 binding 时,可以对一个 queue 绑定多个 header,这种情况下,消息生产者需要告诉 RabbitMQ 匹配哪些 key,producer 可以指定一个标识 x-match,值可以是:
- any - 只有一个值应该匹配。
- all - 所有值都必须匹配。
4. 消息确认
消息到达目的地之后,broker 应该从队列中将其删除,这是为了防止消息过多导致溢出。
删除消息之前,broker 必须得到确认通知。
有 2 种通知方式:
- 自动通知:只要 consumer 接收到消息即可,不管是否处理完成。
- 明确显示通知:只有在 consumer 发送回来一个确认信息后才可以,这样保证 consumer 处理完成后再删除。

推荐阅读:

认识一下 RabbitMQ的更多相关文章
- 消息队列——RabbitMQ学习笔记
消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...
- RabbitMq应用二
在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...
- 如何优雅的使用RabbitMQ
RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...
- RabbitMq应用一的补充(RabbitMQ的应用场景)
直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...
- RabbitMq应用一
RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...
- 缓存、队列(Memcached、redis、RabbitMQ)
本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...
- 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)
Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...
- windows下 安装 rabbitMQ 及操作常用命令
rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...
- RabbitMQ + PHP (三)案例演示
今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...
- RabbitMQ + PHP (二)AMQP拓展安装
上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...
随机推荐
- HDU 5912 Fraction(模拟)
Problem Description Mr. Frog recently studied how to add two fractions up, and he came up with an ev ...
- ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(14)之会员中心管理
源码下载地址:http://www.yealuo.com/Sccnn/Detail?KeyValue=c891ffae-7441-4afb-9a75-c5fe000e3d1c 会员中心,主要包含了会员 ...
- 有状态无状态回话bean
1.有状态(Stateful) 可以在不同的方法调用间保持针对各个客户端的状态 与客户端的联系必须被维持,这样做开销要大一些 有状态也可以这样理解,它存在存储能力,也就是说至少有一个属性来标识它目前的 ...
- 判断移动端还是PC端
window.onload=function(){ var sUserAgent = navigator.userAgent.toLowerCase(); var bIsIpad = sUserAge ...
- 推荐:mysql锁 innodb下的记录锁,间隙锁,next-key锁
你需要知道的 之前我们介绍了排他锁,其实innodb下的记录锁(也叫行锁),间隙锁,next-key锁统统属于排他锁. 行锁 记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁. 生活中的间隙 ...
- Stylized Image Caption论文笔记
Neural Storyteller (Krios et al. 2015) : NST breaks down the task into two steps, which first genera ...
- STM32的RTC晶振不起振的原因及解决方法
STM32的RTC晶振经常出现不起振的问题,这已经是“业界共识”了.很多人在各种电子论坛上求助类似于“求高手指点!RTC晶振不起振怎么办”的问题,而其答案基本可以概括为“这次高手帮不了你了” 更有阴谋 ...
- Delphi XE里的StrPas要注意哦(要让StrPas知道哪里是字符串结束)
废话不多说了,直接上例子解说: procedure TForm1.Button1Click(Sender: TObject);var aa: array[0..1]of AnsiChar; bb1 ...
- java基础 -- 关键字static的用法
static关键字的基本作用就是方便在没有创建对象的情况下调用类的方法/变量, static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问. static ...
- 我的 2019 年 Python 文章榜单
现在是 2020 年的第一天,我相信从昨天开始,各位的信息流里肯定充斥了各式各样的年度盘点/回顾/总结/记录之类的内容.虽然来得稍晚了,但我还是想给诸位送上这一篇文章. 我将在本文中列出自己于 201 ...