RabbitMQ知识详解
一、什么是消息队列
消息队列,即MQ,Message Queue。消息队列是典型的:生产者、消费者模型。生产者不断向消息队列中生产消息,消费者不断的从队列中获取消息。因为消息的生产和消费都是异步的,而且只关心消息的发送和接收,没有业务逻辑的侵入,这样就实现了生产者和消费者的解耦。
MQ是消息通信的模型,并不是具体实现。现在实现MQ的有两种主流方式:AMQP、JMS。
AMQP介绍:
AMQP(高级消息队列协议)提供统一消息服务的应用层标准高级消息队列协议, 是应用层协议的一个开放标准, 为面向消息的中间件设计。角色抽象由生产者,消息代理,消费者,三者可以在不同机器上。该协议目的为保证消息在三者直接传递的可靠性。
AMQP 通常被划分为三层:
模型层:定义了一套命令 (按功能分类),客户端应用可以利用这些命令来实现它的业务功能。
会话层:负责将命令从客户端应用传递给服务器,再将服务器的应答传递给客户端应用,会话层为这个传递过程提供可靠性、同步机制和错误处理。
传输层:提供帧处理、信道复用、错误检测和数据表示。
AMQP与JMS区别:
JMS是定义了统一的接口,来对消息操作进行统一;AMQP是通过规定协议来统一数据交互的格式
JMS限定了必须使用Java语言;AMQP只是协议,不规定实现方式,因此是跨语言的。
MS规定了两种消息模型;而AMQP的消息模型更加丰富。
二、MQ主要解决的问题
MQ的发展,伴随着软件架构的发展,解决软件架构在发展时遇到的问题。上世纪80年代初,伴随着用户量和业务复杂性的提升。第一种重要的系统分发技术“远程过程调用(RPC)”诞生了。
RPC(远程过程调用)其中的核心特点:
(1)、RPC是一种通过网络,向远程计算机请求服务,而不需要了解其底层网络技术的协议。
(2)、RPC协议,以传输协议为基础,为两个不同的应用程序间传递数据。
(3)、RPC采用客户端/服务端工作模式。
对远程调用协议的制定和封装,使调用编程更加容易。随之带来的是系统的拆分,系统间调用复杂度和耦合的增加等问题。同时也伴随着分布式架构的演进。
MQ的产生,主要解决如下问题:
(1)、应用系统之间的解耦
(2)、异步处理,提升系统之间的相应速度
(3)、流量削峰,高峰堆积消息,峰后处理消息
(4)、日志处理(ELK)
(5)、纯粹的系统间通讯
常见MQ间的对比
三、RabbitMQ简介
MQ是什么?
消息总线(Message Queue),是一种跨进程、异步的通信机制,用于上下游传递消息。由消息系统来确保消息的可靠传递。
MQ的作用:
应用解耦、异步、流量削锋、数据分发、错峰流控、日志收集等等。
MQ常见的产品:
当前市面上mq的产品很多,比如RabbitMQ、Kafka、ActiveMQ、ZeroMQ和阿里巴巴捐献给Apache的RocketMQ。甚至连redis这种NoSQL都支持MQ的功能。
RabbitMQ:
RabbitMQ是一个开源的消息代理和队列服务器,用来通过普通协议在不同的应用之间共享数据(跨平台跨语言)。RabbitMQ是使用Erlang语言编写,并且基于AMQP协议实现。
1、RabbitMQ消息流程图:
2、生产者(Publisher)与消费者(Consumer)
在 RabbitMQ 的通信过程中,有两个主要的角色:生产者和消费者。类比于邮件通信的发送方和接收方。RabbtiMQ 服务器是不能够产生数据的,是一个用来传递消息的中间商。生产者产生创建消息,然后发布到代理服务器(RabbitMQ),而消费者则从代理服务器获取消息(不是直接找生产者要消息),而且在实际应用中,生产者和消费者也是可以角色互相转换的,所以当我们应用程序连接到 RabbitMQ 服务器时,必须要明确我是生产者呢还是消费者。
3、消息
生产者创建消息,然后发布到 RabbitMQ 服务器中,消息分为两部分:有效内容和内容标签。
有效的内容:可以是任何内容,一个数组,一个集合,甚至二进制数据都可以。RabbitMQ 不会在意你发什么数据,尽管发就行了。
内容标签:描述有效内容,是 RabbitMQ 用来决定谁将获得消息。基于 AMQP 协议的 RabbitMQ 则是通过生产者发送消息附带的内容标签将消息发送给那些消费者。
4、信道(Channel)
生产者产生了消息,然后发布到 RabbitMQ 服务器,发布之前肯定要先连接上服务器,也就是要在应用程序和rabbitmq 服务器之间建立一条 TCP 连接,一旦连接建立,应用程序就可以创建一条 AMQP 信道。信道是建立在“真实的”TCP 连接内的虚拟连接,AMQP 命令都是通过信道发送出去的,每条信道都会被指派一个唯一的ID(AMQP库会帮你记住ID的),不论是发布消息、订阅队列或者接收消息,这些动作都是通过信道来完成的。对于操作系统来说,每次建立和销毁 TCP 会话是非常昂贵的开销,而实际系统中,比如电商双十一,每秒钟高峰期成千上万条连接,一般来说操作系统建立TCP连接是有数量限制的,那么这就会遇到瓶颈。引入信道的概念,我们可以在一条 TCP 连接上创建 N多个信道,这样既能发送命令,也能够保证每条信道的私密性,我们可以将其想象为光纤电缆。
5、交换机(Exchange)与队列(Queue)
交换器和队列都是 RabbitMQ 服务器的一部分,我们知道生产者会将消息发送到 RabbitMQ 服务器,而进入该服务器后,首先进入交换机部分,然后由交换器根据消息附带的内容标签,将消息绑定到相应的队列。我们首先来看什么是队列:
(1)容纳消息的场所,生产者发送到RabbitMQ服务器的消息会在队列中等待消费者消费。
(2)队列是 RabbitMQ 服务器中最后的终点(除非消息进入了黑洞)。
(3)队列可以实现负载均衡,我们可以增加一堆消费者,然后让 RabbitMQ 以循环的方式来均匀的分配消息。
消息进入RabbitMQ 服务器时,会首先将消息发送到交换器,然后交换器会根据特定的路由算法以及消息的内容标签将消息绑定到相应的队列。在 AMQP 协议中有四种交换器:direct、fanout、topic和 headers,每种交换器都实现了不同的路由算法,这也对应 RabbitMQ 工作的几种不同方式。
6、虚拟机(Virtual Host)
最上面那张大图,我画了虚拟主机A以及虚拟主机B,说明在 RabbitMQ 服务器中存在着多个虚拟主机。为了使多个应用之间不会存在冲冲突,所以使用了虚拟机,虚拟主机其实就是一个迷你版的RabbitMQ 服务器,它拥有自己的交换器和队列,更重要的是虚拟主机拥有自己的权限机制,一个服务器能够创建多个虚拟主机。那么我们在使用RabbitMQ服务器的时候,只需要将一个应用程序对应一个虚拟主机,这种各个实例间逻辑上的分离就能够保证不同的应用程序安全的传递消息。默认的虚拟主机是“/”