RabbitMQ实现了AMQP协议,所以RabbitMQ的工作模型也是基于AMQP的。
- Broker:RabbitMQ宿主机。默认端口是5672。
- Connection:无论是生产者发送消息,还是消费者消费消息,都必须要跟Broker之间建立一个连接,这个连接时一个TCP长连接。
- Channel:如果所有的生产者和消费者都直接创建和释放TCP长连接的话,对于Broker来说肯定会造成很大的性能损耗,也会浪费时间。
所以在AMQP里面引入了Channel的概念,它是一个虚拟的拦截。我们把它翻译成通道。这样我们就可以在保持的TCP里面去创建和释放Channel,大大减少了资源消耗。不同的Channel是相互隔离的,每个Channel都有自己的编号。对于每个客户端线程来说,Channel就没必要共享了,各自用自己的Channel。Channel是RabbitMQ原生API里面的最重要的编程接口,也就是说我们定义交换机、队列、绑定关系、发送消费消息,调用的都是Channel上的方法。 - Queue:RabbitMQ在Broker上存储消息的对象就是Queue。这个Queue实际上使用数据库来实现的,名字叫Mesia。和RabbitMQ一样使用ErLang开发。Queue也是生产者和消费者的纽带,生产者发送的消息到达队列,在队列中存储,消费者从队列取消息消费。
- Consumer:消费者消费消息有两种模式:Pull和Push。
- Pull:对应的方法是basicGet。消息存储在服务端,消费者需要主动向服务端拉取消息才能消费。如果每隔一段时间时间获取一次消息,消息的实时性会降低,但好处是消费端可以根据自己的消费能力决定拉取的频率。
- Push:对应方法是basicConsumer,只要生产者发消息到服务器,就会马上推送给消费者,实时性很高。
- FIFO:由于Queue是FIFO的特性,只有确定前一条消息被消费者消费之后,Broker才会投递下一条消息。
- Exchange:路由消息的组件。生产者发送的消息由Exchange接收,然后路由到目标Queue进行发送。Exchange不存储消息,只根据规则分发消息。Exchange和需要接收消息的队列必须建立一个绑定关系,并且为每个队列指定一个特殊的标识。Exchange和Queue是多对多的关系。
- VHost:在一个Broker能进行业务隔离,避免在一个服务器上安装多个RabbitMQ。不同的VHost使用不同的端口,Exchange和Queue完全隔离。
消息路由方式
Direct 直连
一个队列与直连类型的减缓及绑定,需要指定一个明确的绑定键(binging key)。生产者发送消息时会携带一个路由键(routing key)。当消息的路由键与某个队列的绑定见完全匹配时,这条消息才会从Exchange路由到这个队列上。多个队列也可以使用相同的绑定键。
例如:channel.basicPublish(“MY_DIRECT_EXCHANGE”,“spring”,“msg1”);只有spring queue能收到消息。直连类型的交换机,适用于一些业务用途明确的消息。
topic主题
一个队列与主题类型的交换机绑定时,可以在绑定键中使用通配符。支持两个通配符:
- #:代表0个或者多个单词
- *:代表只有一个单词
单词指的时用英文的点"."隔开的字符。例如:a.vd.fds是3个单词。
解读: - junior queue:支持路由键以junior开头的消息路由,后面可以有0到多个单词。
- netty queue:支持路由键以netty结尾的消息路由,前面可以有0到多个单词。
- senior queue:支持以senior开头的消息路由,后面只能有一个单词。
- jvm queue:支持以jvm结尾的消息路由,前面只能有一个单词。
Fanout广播
广播类型的交换机与队列绑定时,不需要指定绑定键。因此生产者发送消息到广播类型的交换机上,也不需要携带路由键。消息到达交换机时,所有与之绑定了的队列都会收到相同的消息。
例如:channel.basicPublish(“Fanout Exchange”,"",“msg”);三个队列都会收到msg消息。
广播类型的消息适用于一些通用的业务消息。