1 RabbitMQ 简介
1.1 介绍
RabbitMQ 是一个由 erlang 开发的基于 AMQP(Advanced Message Queue)协议的开源实现。用于在分布式系统中存储转发消息,在易用性、扩展性、高可用性等方面都很是的优秀,是当前最主流的消息中间件之一。RabbitMQ 官网:http://www.rabbitmq.com编程
1.2 AMQP
AMQP 是应用层协议的一个开放标准,为面向消息的中间件设计。消息中间件主要用于组件之间的解耦,消息的发送者无需知道消息使用者的存在,一样,消息使用者也不用知道发送者的存在。AMQP 的主要特征是面向消息、队列、路由(包括点对点和发布/订阅)、可靠性、安全。安全
1.3 系统架构
服务器
消息队列的使用过程大概以下:架构
客户端链接到消息队列服务器,打开一个 channel;
客户端声明一个 exchange,并设置相关属性;
客户端声明一个 queue,并设置相关属性;
客户端使用 routing key,在 exchange 和 queue 之间创建好绑定关系;
客户端投递消息到 exchange,exchange 接收到消息后,就根据消息的 key 和已经设置的 binding,进行消息路由,将消息投递到一个或多个队列里。
如上图所示:AMQP 里主要说两个组件,Exchange 和 Queue。绿色的X就是 Exchange ,红色的是 Queue ,这二者都在 Server 端,又称做 Broker,这部分是 RabbitMQ 实现的,而蓝色的则是客户端,一般有 Producer 和 Consumer 两种类型。异步
1.4 几个概念
P: 为 Producer,数据的发送方;
C:为 Consumer,数据的接收方;
Exchange:消息交换机,它指定消息按什么规则,路由到哪一个队列;
Queue:消息队列载体,每一个消息都会被投入到一个或多个队列;
Binding:绑定,它的做用就是把 exchange 和 queue 按照路由规则绑定起来;
Routing Key:路由关键字,exchange 根据这个关键字进行消息投递;
vhost:虚拟主机,一个 broker 里能够开设多个 vhost,用做不一样用户的权限分离;
channel:消息通道,在客户端的每一个链接里,可创建多个 channel,每一个 channel 表明一个会话任务。分布式
4 四种 Exchange 模式
AMQP 协议中的核心思想就是:生产者和消费者隔离,生产者从不直接将消息发送给队列。生产者一般不知道是否一个消息会被发送到队列中,只是将消息发送到一个交换机。先由 Exchange 来接收,而后 Exchange 按照特定的策略转发到 Queue 进行存储。同理,消费者也是如此。Exchange 就相似于一个交换机,转发各个消息分发到相应的队列中。线程
RabbitMQ 提供了四种 Exchange 模式:fanout、direct、topic、header. 因为 header 模式在实际使用中较少,所以本节只对前三种模式进行比较。设计
4.1 Fanout Exchange
中间件
全部发送到 Fanout Exchange 的消息都会被转发到与该 Exchange 绑定(Binding)的全部 Queue 上。blog
Fanout Exchange 不须要处理 RouteKey,只须要简单的将队列绑定到 exchange 上,这样发送到 exchange 的消息都会被转发到与该交换机绑定的全部队列上。相似子网广播,每台子网内的主机都得到了一份复制的消息。
因此,Fanout Exchange 转发消息是最快的。
4.2 Direct Exchange
全部发送到 Direct Exchange 的消息被转发到 RouteKey 中指定的 Queue.
Direct 模式可使用 RabbitMQ 自带的 Exchange:default Exchange ,所以不须要将 Exchange 进行任何绑定(binding)操做 。消息传递时,RouteKey 必须彻底匹配,才会被队列接收,不然该消息会被抛弃。
4.3 Topic Exchange
全部发送到 Topic Exchange 的消息被转发到全部关心 RouteKey 中指定 Topic 的 Queue 上,Exchange 将 RouteKey 和某 Topic 进行模糊匹配。此时队列须要绑定一个 Topic,可使用通配符进行模糊匹配,符号#匹配一个或多个词,符号匹配很少很多一个词。所以log.#可以匹配到log.info.oa,可是log. 只会匹配到log.error.
因此,Topic Exchange 使用很是灵活。
5 RPC 远程过程调用
在这一节中,主要讲述 RabbitMQ RPC. 其实,RabbitMQ RPC 就是经过消息队列(Message Queue)来实现 RPC 的功能,就是客户端向服务端发送定义好的 Queue 消息,其中携带的消息就应该是服务端将要调用的方法的参数 ,并使用 Propertis 告诉服务端将结果返回到指定的 Queue.
5.1 RabbitMQ RPC 的特色
Message Queue 把全部的请求消息存储起来,而后处理,和客户端解耦;
Message Queue 引入新的结点,系统的可靠性会受 Message Queue 结点的影响;
Message Queue 是异步单向的消息。发送消息设计成是不须要等待消息处理的完成。
因此对于有同步返回需求的,Message Queue 是个不错的方向。
5.2 普通 PRC 的特色
同步调用,对于要等待返回结果/处理结果的场景,RPC 是能够很是天然直觉的使用方式,固然 RPC 也能够是异步调用;
因为等待结果,客户端会有线程消耗。
若是以异步 RPC 的方式使用,客户端线程消耗能够去掉,但不能作到像消息同样暂存消息请求,压力会直接传导到服务端。
5.3 适用场合说明
但愿同步获得结果的场合,RPC 合适。
但愿使用简单,则 RPC;RPC 操做基于接口,使用简单,使用方式模拟本地调用。异步的方式编程比较复杂。
不但愿客户端受限于服务端的速度等,可使用 Message Queue.
5.4 RabbitMQ RPC工做流程
基本概念:
Callback queue 回调队列,客户端向服务器发送请求,服务器端处理请求后,将其处理结果保存在一个存储体中。而客户端为了得到处理结果,那么客户在向服务器发送请求时,同时发送一个回调队列地址reply_to.
Correlation id 关联标识,客户端可能会发送多个请求给服务器,当服务器处理完后,客户端没法辨别在回调队列中的响应具体和那个请求时对应的。为了处理这种状况,客户端在发送每一个请求时,同时会附带一个独有correlation_id属性,这样客户端在回调队列中根据correlation_id字段的值就能够分辨此响应属于哪一个请求。
流程说明: