RabbitMQ 采用 Erlang 语言开发。Erlang 语言由 Ericson 设计,专门为开发高并发和分布式系统的一种语言,在电信领域使用广泛。
RabbitMQ 基础架构如下图:
RabbitMq官网: https://www.rabbitmq.com/getstarted.html
Broker: 接收和分发消息的应用,RabbitMQ Server就是 Message Broker
Virtual host:出于多租户和安全因素设计的,把 AMQP 的基本组件划分到一个虚拟的分组中,类似于网络中的 namespace 概念。当多个不同的用户使用同一个 RabbitMQ server 提供的服务时,可以划分出多个vhost,每个用户在自己的 vhost 创建 exchange/queue 等
Connection:publisher/consumer 和 broker 之间的 TCP 连接
Channel:如果每一次访问 RabbitMQ 都建立一个 Connection,在消息量大的时候建立 TCP Connection的开销将是巨大的,效率也较低。Channel 是在 connection 内部建立的逻辑连接,如果应用程序支持多线程,通常每个thread创建单独的 channel 进行通讯,AMQP method 包含了channel id 帮助客户端和message broker 识别 channel,所以 channel 之间是完全隔离的。
Channel 作为轻量级的 Connection 极大减少了操作系统建立 TCP connection 的开销
Exchange:message 到达 broker 的第一站,根据分发规则,匹配查询表中的 routing key,分发消息到queue 中去。常用的类型有:direct (point-to-point), topic (publish-subscribe) and fanout (multicast) ,and headers
Queue:消息最终被送到这里等待 consumer 取走
Binding:exchange 和 queue 之间的虚拟连接,binding 中可以包含 routing key。Binding 信息被保存到 exchange 中的查询表中,用于 message 的分发依据
参见官网具体讲解:https://www.rabbitmq.com/getstarted.html
1 "Hello World!" 模式
2:工作队列模式
3:Publish/Subscribe 发布订阅模式
4: Routing路由模式
5: Topics 通配符模式
6:RPC 模式
7:Publisher Confirms 发布者确认模式,Publisher Confirms 是实现可靠发布的 RabbitMQ 扩展
其中rpc模式更多的是一个远程调用,关于几种工作模式的使用demo可以参考我的git仓库代码:
https://gitee.com/ITLULU/fairy-MQ/tree/sp1/rabbitmq/spring-rabbitmq
简单总结下:
1:hello world模式不需要交换机,product直接将消息暂存在队列中,消费者根据自己消费的队列数据,从队列中拉取数据消费 ,发布者发送的消息只能有一个消费者消费到,如果有多个消费者的话,其他消费者消费不到消息
2:工作队列模式相比hello world模式的多了一些消费者,可以有多个消费端消费消息(工作队列模式实际上会将队列绑定到默认的交换机上)
3:发布订阅模式 和redis的这种订阅类似的,消费者只消费订阅了的消息,相比较前面的两种多了一个交换机,发送者将消息通过交换机转发到绑定的队列,消费者根据自己订阅的消息从队列获取
4: 路由模式: 队列和交换机不再是任意绑定了,而是通过一个 routing key(路由Key),消费发送到交换机时,交换机会根据routing key将消息传递到符合的队列
5:通配符模式: 和路由模式不同的就是可以使用pattern来指定routingkey
6: rpc
7: 发送者消息确认ack: 为了保证消息传递的安全,取消自动确认,而是手动模式,这里涉及到消息确认的两种状态: confirm 和 return
对于发送者将消息成功发送到交换机的消息(也就消息发送到了broker),会返回一个confirm,(confirm的结果可能是两种情况;
1:ack 表示broker接收了数据; 2:nack, 表示broker拒收消息, 原因很多 ,如队列已满, 限流,IO异常等)
而return则表示 broker正常接收ack后,但是broker交换机找不到对应的队列进行投递,会将消息返回给生产者或者扔到死信队列,这两种状态只是表示生产者与broker之间消息传递的情况,与消费者是否接收以及消息消费确认成功无关
交换机一方面接收生产者发送的消息,另外一方面知道如何将消息传递到哪一个队列,如递交所有队列,递交给指定队列,或者丢弃消息。具体如何操作需要根据交换机的类型,交换机按照官网所说有四种类型
1:fanout(广播类型)将消息交给所有绑定到该交换机的队列中
2:Direct(定向)只将消息交给符合指定routing key的队列
3:topic (通配符) j将消息交给符合routing pattern(路由模式)的队列
4:header(header类型)header类型的Exchange与Routing有点类似,不同的是,header类型的Exchange取消了Routing Key,使用key/value来匹配队列
Topic 类型与 Direct 相比,都是可以根据 RoutingKey 把消息路由到不同的队列。
只不过 Topic 类型Exchange 可以让队列在绑定 Routing key 的时候使用通配符!
Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert
通配符规则:# 匹配一个或多个词,* 匹配不多不少恰好1个词,例如:item.# 能够匹配 item.insert.abc 或者 item.insert,item.* 只能匹配 item.insert
header的匹配有两种方式,一种是all另一种是any。这两种方式是在接收端必须要用键值"x-mactch"来定义。
all:代表必须匹配Consumer端的所有键值对
any:代表只要匹配Consumer端的任意一个键值对即可