分布式系统中,如何在各个应用之间高效的进行通信,是系统设计中的一个关键。

使用 消息代理(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 keybinding key 进行模式匹配。

Routing key == Pattern in binding key

RabbitMQ 使用 *# 这2个通配符。

* - 匹配一个词。

# - 匹配 0 个或多个词。

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

routing keylogs.success 的消息,匹配binding key -- #successlogs.*,所以消息会进入 "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的更多相关文章

  1. 消息队列——RabbitMQ学习笔记

    消息队列--RabbitMQ学习笔记 1. 写在前面 昨天简单学习了一个消息队列项目--RabbitMQ,今天趁热打铁,将学到的东西记录下来. 学习的资料主要是官网给出的6个基本的消息发送/接收模型, ...

  2. RabbitMq应用二

    在应用一中,基本的消息队列使用已经完成了,在实际项目中,一定会出现各种各样的需求和问题,rabbitmq内置的很多强大机制和功能会帮助我们解决很多的问题,下面就一个一个的一起学习一下. 消息响应机制 ...

  3. 如何优雅的使用RabbitMQ

    RabbitMQ无疑是目前最流行的消息队列之一,对各种语言环境的支持也很丰富,作为一个.NET developer有必要学习和了解这一工具.消息队列的使用场景大概有3种: 1.系统集成,分布式系统的设 ...

  4. RabbitMq应用一的补充(RabbitMQ的应用场景)

    直接进入正题. 一.异步处理 场景:发送手机验证码,邮件 传统古老处理方式如下图 这个流程,全部在主线程完成,注册->入库->发送邮件->发送短信,由于都在主线程,所以要等待每一步完 ...

  5. RabbitMq应用一

    RabbitMq应用一 RabbitMQ的具体概念,百度百科一下,我这里说一下我的理解,如果有少或者不对的地方,欢迎纠正和补充. 一个项目架构,小的时候,一般都是传统的单一网站系统,或者项目,三层架构 ...

  6. 缓存、队列(Memcached、redis、RabbitMQ)

    本章内容: Memcached 简介.安装.使用 Python 操作 Memcached 天生支持集群 redis 简介.安装.使用.实例 Python 操作 Redis String.Hash.Li ...

  7. 消息队列性能对比——ActiveMQ、RabbitMQ与ZeroMQ(译文)

    Dissecting Message Queues 概述: 我花了一些时间解剖各种库执行分布式消息.在这个分析中,我看了几个不同的方面,包括API特性,易于部署和维护,以及性能质量..消息队列已经被分 ...

  8. windows下 安装 rabbitMQ 及操作常用命令

    rabbitMQ是一个在AMQP协议标准基础上完整的,可服用的企业消息系统.它遵循Mozilla Public License开源协议,采用 Erlang 实现的工业级的消息队列(MQ)服务器,Rab ...

  9. RabbitMQ + PHP (三)案例演示

    今天用一个简单的案例来实现 RabbitMQ + PHP 这个消息队列的运行机制. 主要分为两个部分: 第一:发送者(publisher) 第二:消费者(consumer) (一)生产者 (创建一个r ...

  10. RabbitMQ + PHP (二)AMQP拓展安装

    上篇说到了 RabbitMQ 的安装. 这次要在讲案例之前,需要安装PHP的AMQP扩展.不然可能会报以下两个错误. 1.Fatal error: Class 'AMQPConnection' not ...

随机推荐

  1. HDU 5912 Fraction(模拟)

    Problem Description Mr. Frog recently studied how to add two fractions up, and he came up with an ev ...

  2. ASP.NET MVC 实现页落网资源分享网站+充值管理+后台管理(14)之会员中心管理

    源码下载地址:http://www.yealuo.com/Sccnn/Detail?KeyValue=c891ffae-7441-4afb-9a75-c5fe000e3d1c 会员中心,主要包含了会员 ...

  3. 有状态无状态回话bean

    1.有状态(Stateful) 可以在不同的方法调用间保持针对各个客户端的状态 与客户端的联系必须被维持,这样做开销要大一些 有状态也可以这样理解,它存在存储能力,也就是说至少有一个属性来标识它目前的 ...

  4. 判断移动端还是PC端

    window.onload=function(){ var sUserAgent = navigator.userAgent.toLowerCase(); var bIsIpad = sUserAge ...

  5. 推荐:mysql锁 innodb下的记录锁,间隙锁,next-key锁

    你需要知道的 之前我们介绍了排他锁,其实innodb下的记录锁(也叫行锁),间隙锁,next-key锁统统属于排他锁. 行锁 记录锁其实很好理解,对表中的记录加锁,叫做记录锁,简称行锁. 生活中的间隙 ...

  6. Stylized Image Caption论文笔记

    Neural Storyteller (Krios et al. 2015) : NST breaks down the task into two steps, which first genera ...

  7. STM32的RTC晶振不起振的原因及解决方法

    STM32的RTC晶振经常出现不起振的问题,这已经是“业界共识”了.很多人在各种电子论坛上求助类似于“求高手指点!RTC晶振不起振怎么办”的问题,而其答案基本可以概括为“这次高手帮不了你了” 更有阴谋 ...

  8. Delphi XE里的StrPas要注意哦(要让StrPas知道哪里是字符串结束)

    废话不多说了,直接上例子解说: procedure TForm1.Button1Click(Sender: TObject);var  aa: array[0..1]of AnsiChar;  bb1 ...

  9. java基础 -- 关键字static的用法

    static关键字的基本作用就是方便在没有创建对象的情况下调用类的方法/变量, static关键字修饰的方法或者变量不需要依赖于对象来进行访问,只要类被加载了,就可以通过类名去进行访问. static ...

  10. 我的 2019 年 Python 文章榜单

    现在是 2020 年的第一天,我相信从昨天开始,各位的信息流里肯定充斥了各式各样的年度盘点/回顾/总结/记录之类的内容.虽然来得稍晚了,但我还是想给诸位送上这一篇文章. 我将在本文中列出自己于 201 ...