一:何为RabbitMQ?

作为Windows忠实用户,不得不提微软自带的MSMQ,Windows自带的一个服务,message是存放在文件系统的,这是最原始的消息队列了。

然而如今的分布式以及消息处理,必须要满足【集群,消息确认,内存化,高可用以及镜像】,这些就是最新的消息队列,如 ActiveMQ,ZereMQ,RabbitMQ等。

二:RabbitMQ的本质

1.RabbitMQ是用Erlang语言写的

2.遵循[AMQP]协议,一种高级队列协议

也就是,RabbitMQ是遵循AMQP协议并用erlang代码实现的消息系统

三:整体架构

几个基本概念还是需要了解的:

  RabbitMQ Server

  也叫Broker Server,它不是运送食物的卡车,而是一种传输服务。原话是RabbitMQ isn't a food truck, it's a delivery service. 它的角色就是维护一条从Producer到Consumer的路线,保证数据能够按照指定的        方式进行传输。虽然这个保证也不是100%的保证,但是对于普通的应用来说这已经足够了。当然对于商业系统来说,可以再做一层数据一致性的guard,就可以彻底保证系统的一致性了。

 Client P

也叫Producer,数据的发送方。Create messages and publish (send) them to a Broker Server (RabbitMQ)。一个Message有两个部分:payload(有效载荷)和label(标签)。payload顾名思义就是传输的          数据。label是exchange的名字或者说是一个tag,它描述了payload,而且RabbitMQ也是通过这个label来决定把这个Message发给哪个Consumer。AMQP仅仅描述了label,而RabbitMQ决定了如何使                    用这个label的规则。

 Client C

也叫Consumer,数据的接收方。Consumers attach to a Broker Server (RabbitMQ) and subscribe to a queue。把queue比作是一个有名字的邮箱。当有Message到达某个邮箱后,RabbitMQ把它发送给它的        某个订阅者即Consumer。当然可能会把同一个Message发送给很多的Consumer。在这个Message中,只有payload,label已经被删掉了。对于Consumer来说,它是不知道谁发送的这个信息的,就是                    协议本身不支持。当然了,如果Producer发送的payload包含了Producer的信息就另当别论了。

对于一个数据从Producer到Consumer的正确传递,还有三个概念需要明确:exchanges, queues and bindings。

  • Exchanges are where producers publish their messages.

  • Queues are where the messages end up and are received by consumers.

  • Bindings are how the messages get routed from the exchange to particular queues.

还有几个概念是上述图中没有标明的,那就是Connection(连接)和Channel(通道,频道)。

Connection

就是一个TCP的连接。Producer和Consumer都是通过TCP连接到RabbitMQ Server的。以后我们可         以看到,程序的起始处就是建立这个TCP连接。

Channel

虚拟连接。它建立在上述的TCP连接中。数据流动都是在Channel中进行的。也就是说,一般情况是          程序起始建立TCP连接,第二步就是建立这个Channel。

那么,为什么使用Channel,而不是直接使用TCP连接?

对于OS来说,建立和关闭TCP连接是有代价的,频繁的建立关闭TCP连接对于系统的性能有很           大的影响,而且TCP的连接数也有限制,这也限制了系统处理高并发的能力。但是,在TCP连接中建         立Channel是没有上述代价的。对于Producer或者Consumer来说,可 以并发的使用多个                            Channel进行Publish或者Receive。有实验表明,1s的数据可以Publish10K的数据包。当然对于不同         的硬件环境,不同的数据包大小这个数据肯定不一样,但是我只想说明,对于普通的Consumer或者         Producer来说,这已经足够了。如果不够用, 你考虑的应该是如何细化SPLIT你的设计。

四:四种交换机:

RabbitMQ常用的Exchange Type有fanout、direct、topic、headers这四种(AMQP规范里还提到两种Exchange Type,分别为system与自定义,这里不予以描述),下面分别进行介绍。

1.fanout

fanout类型的Exchange路由规则非常简单,它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。

上图中,生产者(P)发送到Exchange(X)的所有消息都会路由到图中的两个Queue,并最终被两个消费者(C1与C2)消费。

2.direct

direct类型的Exchange路由规则也很简单,它会把消息路由到那些Binding key与Routing key完全匹配的Queue中。

以上图的配置为例,我们以routingKey="error"发送消息到Exchange,则消息会路由到Queue1(amqp.gen-S9b…,这是由RabbitMQ自动生成的Queue名称)和Queue2(amqp.gen-Agl…);如果我们以             Routing Key="info"或routingKey="warning"来发送消息,则消息只会路由到Queue2。如果我们以其他Routing Key发送消息,则消息不会路由到这两个Queue中。

3.topic

前面讲到direct类型的Exchange路由规则是完全匹配Binding Key与Routing Key,但这种严格的匹配方式在很多情况下不能满足实际业务需求。topic类型的Exchange在匹配规则上进行了扩展,它与direct类          型的Exchage相似,也是将消息路由到Binding Key与Routing Key相匹配的Queue中,但这里的匹配规则有些不同,它约定:

Routing Key为一个句点号“.”分隔的字符串(我们将被句点号". "分隔开的每一段独立的字符串称为一个单词),如"stock.usd.nyse"、"nyse.vmw"、"quick.orange.rabbit"。Binding Key与Routing Key一样也            是 句点号“. ”分隔的字符串。

Binding Key中可以存在两种特殊字符"*"与"#",用于做模糊匹配,其中"*"用于匹配一个单词,"#"用于匹配多个单词(可以是零个)。

以上图中的配置为例,routingKey=”quick.orange.rabbit”的消息会同时路由到Q1与Q2,routingKey=”lazy.orange.fox”的消息会路由到Q1,routingKey=”lazy.brown.fox”的消息会路由到Q2,                                      routingKey=”lazy.pink.rabbit”的消息会路由到Q2(只会投递给Q2一次,虽然这个routingKey与Q2的两个bindingKey都匹配);routingKey=”quick.brown.fox”、routingKey=”orange”、                                              routingKey=”quick.orange.male.rabbit”的消息将会被丢弃,因为它们没有匹配任何bindingKey。

4.headers

headers类型的Exchange不依赖于Routing Key与Binding Key的匹配规则来路由消息,而是根据发送的消息内容中的headers属性进行匹配。

在绑定Queue与Exchange时指定一组键值对;当消息发送到Exchange时,RabbitMQ会取到该消息的headers(也是一个键值对的形式),对比其中的键值对是否完全匹配Queue与Exchange绑定时指定的          键值对。如果完全匹配则消息会路由到该Queue,否则不会路由到该Queue。

该类型的Exchange没有用到过(不过也应该很有用武之地),所以不做介绍。

RabbitMQ探索之路(一):RabbitMQ简介的更多相关文章

  1. RabbitMQ 入门 (Go) - 1. 简介和安装

    Message Broker(消息代理) 维基百科对 Message Broker 的定义是:Message broker 是一种中介程序模块,它把消息从发送方的正式消息传递协议转化为接收方的正式消息 ...

  2. RabbitMQ探索之路(二):RabbitMQ在Linux下的安装

    引言 消息队列现在在互联网项目中应用的还是非常多的,在接下来的博客中小编会深入的了解MQ的实现过程,在此博客中将介绍如何在centos7下面安装MQ以及遇到的问题. 第一步:安装Erlang 因为ra ...

  3. RabbitMQ入门到进阶(Spring整合RabbitMQ&SpringBoot整合RabbitMQ)

    1.MQ简介 MQ 全称为 Message Queue,是在消息的传输过程中保存消息的容器.多用于分布式系统 之间进行通信. 2.为什么要用 MQ 1.流量消峰 没使用MQ 使用了MQ 2.应用解耦 ...

  4. .NET文件并发与RabbitMQ(初探RabbitMQ)

    本文版权归博客园和作者吴双本人共同所有.欢迎转载,转载和爬虫请注明原文地址:http://www.cnblogs.com/tdws/p/5860668.html 想必MQ这两个字母对于各位前辈们和老司 ...

  5. Github开源:Sheng.RabbitMQ.CommandExecuter (RabbitMQ 的命令模式实现)

    [Github]:https://github.com/iccb1013/Sheng.RabbitMQ.CommandExecuter Sheng.RabbitMQ.CommandExecuter 是 ...

  6. RabbitMQ(1) - win+rabbitMQ

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

  7. RabbitMQ系列之RabbitMQ单机安装

    安装epel源 rpm -ivh http://download.fedoraproject.org/pub/epel/6/x86_64/epel-release-6-8.noarch.rpm #ht ...

  8. (二)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念

    原文:(二)RabbitMQ消息队列-RabbitMQ消息队列架构与基本概念 没错我还是没有讲怎么安装和写一个HelloWord,不过快了,这一章我们先了解下RabbitMQ的基本概念. Rabbit ...

  9. (一)RabbitMQ消息队列-RabbitMQ的优劣势及产生背景

    原文:(一)RabbitMQ消息队列-RabbitMQ的优劣势及产生背景 本篇并没有直接讲到技术,例如没有先写个Helloword.我想在选择了解或者学习一门技术之前先要明白为什么要现在这个技术而不是 ...

  10. .NET Core RabbitMQ探索(2)——RabbitMQ的Exchange

    实际上,RabbitMQ的生产者并不会直接把消息发送给队列,甚至生产者都不知道消息是否会被发送给一个队列.对于生产者而言,它们只能把消息发送到Exchange,一个Exchange所完成的工作相当简单 ...

随机推荐

  1. ConcurrentSkipListMap--跳表的简单使用

    import java.util.Map; import java.util.concurrent.ConcurrentSkipListMap; /** * 跳表的使用 */ public class ...

  2. postgre存储过程或者视图中"::"双冒号是什么意思

    双冒号是类型转换的意思. 比如: '2019-09-10'::date

  3. js append()和appendChild()和insertBefore()的区别

    <body> <input type="button" value="删除" id="btn"> <scrip ...

  4. CSU 1503: 点到圆弧的距离(计算几何)

    题目描述 输入一个点 P 和一条圆弧(圆周的一部分),你的任务是计算 P 到圆弧的最短距离.换句话 说,你需要在圆弧上找一个点,到 P点的距离最小. 提示:请尽量使用精确算法.相比之下,近似算法更难通 ...

  5. BZOJ 2694: Lcm 莫比乌斯反演 + 积性函数 + 线性筛 + 卡常

    求 $\sum_{i=1}^{n}\sum_{j=1}^{m}lcm(i,j)\mu(gcd(i,j))^2$   $\Rightarrow \sum_{d=1}^{n}\mu(d)^2\sum_{i ...

  6. LUOGU P4088 [USACO18FEB]Slingshot(线段树)

    传送门 解题思路 推了推式子发现是个二维数点,想了想似乎排序加线段树难写,就写了个树套树,结果写完看见空间才\(128M\)..各种奇技淫巧卡空间还是\(MLE\)到天上.后来只好乖乖的写排序+线段树 ...

  7. BUUCTF | CODE REVIEW 1 (反序列化,md5绕过)

    <?php /** * Created by PhpStorm. * User: jinzhao * Date: 2019/10/6 * Time: 8:04 PM */ highlight_f ...

  8. JS当中的无限分类递归树

    列表转换成树形结构方法定义: //javascript 树形结构 function toTree(data) { // 删除 所有 children,以防止多次调用 data.forEach(func ...

  9. VS中C语言scanf函数报错

    在VS中创建C项目使用scanf方法时会如下报错 解决方案 方法1:文件中设置 在第一行设置代码    #define _CRT_SECURE_NO_WARNINGS 或者添加警告忽略     #pr ...

  10. 105、TensorFlow的变量(一)

    import tensorflow as tf mammal = tf.Variable("Elephant", tf.string) ignition = tf.Variable ...