RabbitMQ是消息队列中间件(Message Queue Middleware)中一种,工做虽然有用到,可是却没有造成很好的总体包括,主要是一些基础概念的认识,这里经过阅读《RabbitMQ实战指南》整理笔记并进行代码实践,更好地理解RabbitMQ!html
本文只经过讲解RabbitMQ的一些基础概念,主要是RabbitMQ的“生产者-消费者”模型涉及到的交换器、路由键、绑定键、消息路由规则等,下一篇RabbitMQ是如何运转的?会有简单介绍RabbitMQ的运转、RabbitMQ部署,Java代码实践。java
须要电子书PDF版《RabbitMQ实战指南》(高清带标签)能够评论或者联系我服务器
讲解RabbitMQ以前先认识下MQ做为消息中间件的做用(优势),使用的时候若是不去思考为何用MQ,怎样更好地才能达到它的做用的话,那都是毫无心义的使用!网络
一、解耦:能够很好地屏蔽应用程序及平台之间的特性,充当中间者,松散耦合应用程序及平台,它们彼此不须要了解远程过程调用RPC与网络协议的细节;异步
二、异步通讯:能提供C/S之间同步与异步链接,在任什么时候刻均可以将消息进行传送或者存储转发;post
三、可恢复性:当消息接收方宕机或网络不通的状况下,消息转储于MQ中,直到网络恢复或接收方恢复再进行转发;性能
四、扩展性:提升消息入队列和处理效率是容易的,只须要另外增长处理过程便可,不须要改变代码,也不须要调节参数。url
五、顺序性:因为大部分MQ支持队列模式,天然也就能保证必定的数据处理顺序(事实上是不许确的,颇有局限性。消息的顺序性取决于不少因素)spa
六、缓冲:MQ经过一个缓冲层来帮助任务最高效率执行,写入MQ的处理会尽量快速。3d
RabbitMQ总体的模型实际上是一种“生产者-消费者”模型,发送消息的一方称之为生产者,接收消息一方称之为消费者。中间会有交换器、队列、Broker等概念。下图是简单的RabbitMQ的模型图(截图来自于《RabbitMQ实战指南》,如下截图同)
(1)Producer:
投递消息的一方,建立了消息以后发布到RabbitMQ中,消息主要包括消息体(Payload)与Label标签,消息体能够一般是业务数据,好比JSON等,Label则用来表述这条消息,好比一个交换机名称和一个路由键。
生产者把消息交由RabbitMQ,以后会根据标签把消息发送给感兴趣的消费者。
(2 Consumer:
消费者,接收消息的一方,链接到RabbitMQ服务器,并订阅到队列上,当消费者消费一条消息时只是消费了消息体payload,在消息路由过程当中,消息的标签会丢失,存入队列中只有消息体。消费者不须要知道生产者是谁。
(3)Broker:
消息中间件的服务节点,一个RabbitMQ Broker能够简单地看作一个RabbitMQ服务节或者RabbitMQ服务实例(大多数状况下能够看作是一台RabbitMQ的服务器)
由上图可知,消息队列运转过程是这样的:
封装好的消息发送(AMQP命令为Basic.publish)到Broker中,消费者订阅并接收(Basic.Get/Basic.Consume)消息,以后再进行业务逻辑处理(能够再开另外的进程,不须要与接收消息同一个进程)
RabbitMQ中消息都只能存储在队列中,当多个消费者订阅一个队列时,队列中的消息会被平均分摊(Round-Robin),也就是并非每一个消费者都能收到全部的消息并处理。
注意如下几点:
1)对于生产者生产的消息到队列中,并非平均分摊。而是经过路由键、绑定键、交换器类型三个决定消息最终被哪一个消费者消费,以后会介绍!
2)生产者与消费者之间的链接,并不仅是经过队列那么简单链接,而是外加经过TCP链接与信道Channel,以后也会介绍
(1) 交换器(Exchange, X):由上图交换机模型图中看不到交换器这个东西,但其实是存在的,生产者将消息投递到队列,然而真实状况是:生产者将消息发送到Exchange,由Exchange再路由到一个或多个队列中;
交换器的类型有fanout、direct、topic、headers这四种类型,不一样的类型的交换器有其独特的匹配规则,这里的匹配规则其实就是决定消息最终路由到哪的队列的关键,具体请往下看
(2) 路由键(RoutingKey):生产者将消息发送给交换器的时候,会指定RoutingKey指定路由规则,实际状况是须要将RoutingKey、交换器类型、绑定键联合使用才能最终生效。当交换器类型与BindingKey固定状况下,经过执行RoutingKey来决定消息流向哪里。
(3)绑定(BindingKey):经过绑定键将交换器与队列关联起来,这样RabbitMQ就知道如何正确地将消息路由到队列,其实绑定键也是一种路由键的一种,不过是用在绑定交换器与队列的时候。
总结有如下三点:
(1) 生产者将消息发送给哪一个Exchange是须要由RoutingKey决定的,生产者须要将Exchange与哪一个队列绑定时须要由BindingKey决定的(固然还要看交换器类型,BindingKey不必定会生效,如fanout类型交换器);
(2) 生产者将消息发送给交换器时,须要一个RoutingKey,当BindingKey和RoutingKey相匹配时,消息会被路由到对象的队列中(固然也要看交换器类型)。
(3) BindingKey其实也属于路由键的一种,在使用邦定的时候,须要的路由键是BingdingKey,在发送消息的时,须要的路由键是RoutingKey
为何非要介绍交换器类型呢?上文中也提到过交换器类型关系到具体的消息路由途径,处路由键、绑定键以外的还须要关注交换器的类型。不一样的交换器会有不一样的匹配规则。
RabbitMQ经常使用的交换器类型有fanout、direct、topic、headers这四种类型
(1)fanout:它会把全部的交换器上的消息路由到全部与该交换器邦定的队列中,不须要BindingKey生效
(2)direct:它会把消息路由到BindingKey与RoutingKey彻底匹配的队列中。好比在发送消息的时候,设置Label中RoutingKey为warning,则消息会路由到Queue1与Queue2上(请看下图)。
(3)topic:是direct上的扩展,一样是利用RoutingKey与BindingKey相匹配,可是匹配规则不同,支持模糊匹配。有以下的规则
好比:
RoutingKey为com.hidden.client的消息只会到队列Queue2中:由于只有Queue2的BindingKey=*.*.client匹配com.hidden.client
RoutingKey为com.rabbitmq.client的消息会到队列Queue1-2中: 由于Queue1的BindingKey=*.rabbitmq.*.匹配com.rabbitmq.client,Queue2的BindingKey=*.*.client匹配com.rabbitmq.client
RoutingKey为java.rabbitmq.demo的消息只会到队列Queue1中:由于只有Queue1的BindingKey=*.rabbitmq.*.匹配java.rabbitmq.demo
RoutingKey为java.util.concurrent的消息会被丢弃或者返回给生产者(须要设置)
(4)headers:依赖发送消息内容中的hearders属性进行匹配,在绑定队列和交换器时指定一组键值对,这里的也就是headers,当发送消息到交换器时,RabbitMQ会获取到该消息的headers,经过比较会路由到相关队列中,这种交换器性能会不好,通常不会使用。
以上内容总结起来只是介绍了RabbitMQ的从生产者产生消息到消费者消费消息过程当中涉及到的概念。还未介绍具体的RabbitMQ是如何运转的,好比生产者是怎样创建链接生成消息的,消费者又是怎样读取消息的,这将是下一篇RabbitMQ是如何运转的?主要介绍的。