由于RabbitMQ实现了AMQP协议,所以RabbitMQ的工作模型也是基于AMQP的。
image.png

1、Broker

我们要使用RabbitMQ来收发消息,必须要安装一个RabbitMQ的服务,可以安装在Windows上面也可以安装在Linux上面,默认是5672的端口。这台RabbitMQ的服务器我们把它叫做Broker,中文翻译是代理/中介,因为MQ服务器帮助我们做的事情就是存储、转发消息。

2、Connection

无论是生产者发送消息,还是消费者接收消息,都必须要跟Broker之间建立一个连接,这个连接是一个TCP的长连接。

3、Channel

如果所有的生产者发送消息和消费者接收消息,都直接创建和释放TCP长连接的话,对于Broker来说肯定会造成很大的性能损耗,因为TCP连接是非常宝贵的资源,创建和释放也要消耗时间。
所以在AMQP里面引入了Channel的概念,它是一个虚拟的连接。我们把它翻译成通道,或者消息信道。这样我们就可以在保持的TCP长连接里面去创建和释放Channel,大大了减少了资源消耗。另外一个需要注意的是,Channel是RabbitMQ原生API里面的最重要的编程接口,也就是说我们定义交换机、队列、绑定关系,发送消息消费消息,调用的都是Channel接口上的方法。
https://stackoverflow.com/questions/18418936/rabbitmq-and-relationship-

4、Queue

现在我们已经连到Broker了,可以收发消息了。在其他一些MQ里面,比如ActiveMQ和Kafka,我们的消息都是发送到队列上的。
队列是真正用来存储消息的,是一个独立运行的进程,有自己的数据库(Mnesia)。
消费者获取消息有两种模式,一种是Push模式,只要生产者发到服务器,就马上推送给消费者。另一种是Pull模式,消息存放在服务端,只有消费者主动获取才能拿到消息。消费者需要写一个while循环不断地从队列获取消息吗?不需要,我们可以基于事件机制,实现消费者对队列的监听。

由于队列有FIFO的特性,只有确定前一条消息被消费者接收之后,才会把这条消息从数据库删除,继续投递下一条消息。

5、Exchange

在RabbitMQ里面永远不会出现消息直接发送到队列的情况。因为在AMQP里面引入了交换机(Exchange)的概念,用来实现消息的灵活路由。
交换机是一个绑定列表,用来查找匹配的绑定关系。
队列使用绑定键(BindingKey)跟交换机建立绑定关系。
生产者发送的消息需要携带路由键(RoutingKey),交换机收到消息时会根据它保存的绑定列表,决定将消息路由到哪些与它绑定的队列上。
注意:交换机与队列、队列与消费者都是多对多的关系。

6、Vhost

我们每个需要实现基于RabbitMQ的异步通信的系统,都需要在服务器上创建自己要用到的交换机、队列和它们的绑定关系。如果某个业务系统不想跟别人混用一个系统,怎么办?再采购一台硬件服务器单独安装一个RabbitMQ服务?这种方式成本太高了。在同一个硬件服务器上安装多个RabbitMQ的服务呢?比如再运行一个5673的端口?没有必要,因为RabbitMQ提供了虚拟主机VHOST。

VHOST除了可以提高硬件资源的利用率之外,还可以实现资源的隔离和权限的控制。它的作用类似于编程语言中的namespace和package,不同的VHOST中可以有同名的Exchange和Queue,它们是完全透明的。

这个时候,我们可以为不同的业务系统创建不同的用户(User),然后给这些用户分配VHOST的权限。比如给风控系统的用户分配风控系统的VHOST的权限,这个用户可以访问里面的交换机和队列。给超级管理员分配所有VHOST的权限。

参考

咕泡学院三期 RabbitMQ专栏