- 1. RabbitMQ是什么?
- 1.1 RabbitMQ
- 1.2 同类的中间件
- 1.3 工作模式
- 2. RabbitMQ的作用?
- 2.1 解耦
- 2.2 异步
- 2.3 削峰
- 3. RabbitMQ的缺点?
- 3.1 可用性降低
- 3.2 复杂度提高
- 3.3 一致性问题
- 4. 一些概念
- 4.1 信道、交换机、路由键、队列
- 4.2 交换机Exchange的四种类型和用法
- 4.2.1 Direct Exchange
- 4.2.2 Fanout exchange
- 4.2.3 Topic Exchange
- 4.2.4 Headers Exchange
- 参考
- RabbitMQ是一款使用Erlang语言开发的,实现AMQP(高级消息队列协议)的开源消息中间件。
它是典型的生产者消费者模式的消息队列。
“消息队列(Message Queue)”是在消息的传输过程中保存消息的容器。
- 通常有Kafka,ActiveMQ,RocketMQ。参考[2]
|
特性 |
ActiveMQ |
RabbitMQ |
RocketMQ |
Kafka |
|---|---|---|---|---|
|
单机吞吐量 |
万级,比 RocketMQ、Kafka 低一个数量级 |
同 ActiveMQ |
10 万级,支撑高吞吐 |
10 万级,高吞吐,一般配合大数据类的系统来进行实时数据计算、日志采集等场景 |
|
topic 数量对吞吐量的影响 |
topic 可以达到几百/几千的级别,吞吐量会有较小幅度的下降,这是 RocketMQ 的一大优势,在同等机器下,可以支撑大量的 topic |
topic 从几十到几百个时候,吞吐量会大幅度下降,在同等机器下,Kafka 尽量保证 topic 数量不要过多,如果要支撑大规模的 topic,需要增加更多的机器资源 | ||
|
时效性 |
ms 级 |
微秒级,这是 RabbitMQ 的一大特点,延迟最低 |
ms 级 |
延迟在 ms 级以内 |
|
可用性 |
高,基于主从架构实现高可用 |
同 ActiveMQ |
非常高,分布式架构 |
非常高,分布式,一个数据多个副本,少数机器宕机,不会丢失数据,不会导致不可用 |
|
消息可靠性 |
有较低的概率丢失数据 |
基本不丢 |
经过参数优化配置,可以做到 0 丢失 |
同 RocketMQ |
|
功能支持 |
MQ 领域的功能极其完备 |
基于 erlang 开发,并发能力很强,性能极好,延时很低 |
MQ 功能较为完善,还是分布式的,扩展性好 |
功能较为简单,主要支持简单的 MQ 功能,在大数据领域的实时计算以及日志采集被大规模使用 |
- 简单模式
一队列,一消费者、生产者,使用默认交换机,即可构成最基本的模型。
- 工作模式
类似简单模式,但是会有多个消费者,相比于简单模式只是消费端的个数增加了,这种情况适用于生产者生成消息过于快,消费端来不及消费,才会采用多个消费端进行消费,此时rq将会按照轮询的方式分别将消息给予每个消费者。
消费者在没有发送 ack 的情况下死亡(其通道关闭、连接关闭或 TCP 连接丢失)
RabbitMQ 将理解消息未完全处理并将重新排队。如果有其他消费者同时在线,它会迅速将其重新交付给另一个消费者
- 订阅模式
结合交换机实现一端生产,多个消费者可以都接收消费到相同的消息。
实现该模式,主要基于扇形交换机fanout完成,他的特点是,将消息发布至绑定在交换机上的所有队列中。
- 路由模式
通过结合交换器direct模式,可以为队列绑定指定routing_key路由规则,让交换器可以选择的为某些队列进行消息投递。(队列和路由key是一对一的)
- 主题模式
主题模式,借助topic交换机的匹配队列功能,可以使业务代码对于交换机的选择更为灵活,简而言之可以对业务进行包含关键key的分类,而key将作为队列的匹配规则。
- RPC模式
实现rpc机制,需要创建有关于rpc客户端的回调队列,并且为了在回调队列中可以获取响应的详细归属,可以通过维护业务id来分辨。
- 也是消息队列的作用:服务解耦,异步处理和流量控制(削峰)。
- 系统B、C、D需要系统A提供数据,A需要考虑它们是不是收到了,需不需要重发,对应的需求做了改变是不是要对应改代码等问题?
- 使用MQ,系统A作为生产者就只需要将生产的数据交给MQ,其他的就不用管了,它们剩下的系统去取自己需要的数据就行了。
- 同样的场景,如果A等待B、C、D依次完成本地写入操作,那么时间就是他们的操作之和,因为要等待它们写入成功响应后A才会做下一步操作,假如分别的处理时间是200ms,300ms,250ms,那么总共就要750ms,这样就非常耗时。
- 使用MQ,系统A就只管发数据到MQ就行,不需要等待响应结果,比如总共发送时间是5ms,那么就耗时5ms,不需要等待它们处理完。
- 比如平时MySQL处理请求的峰值是2000条/s,平时也就几百上千条每秒的数据请求,但是有特殊情况,如双11抢东西等,出现上万条每秒的数据请求,会瞬间导致MySQL崩溃,所以为了应对这种情况,我们将数据扔进MQ,然后MySQL去最大程度的拿数据请求,从而不至于让系统崩溃。
- 就是如何保证MQ的高可用,如果MQ崩了那么收发数据的双方都不能进行交互了。
- 引入MQ需要设计需要哪些信息,对应放入哪些队列,对应的生产者和消费者怎么对应收发数据。
- 对于同一个数据,可能要求B、C、D收到一致的数据,但是C系统收的时候出了问题,数据不一致了,那么怎么去保证这种情况的一致性呢?
- 首先是它们之间有一个对应的关系,即信道、交换机、路由键和队列三者的关系。
生产者将消息发送到 Exchange (交换机),由交换机将消息路由到一个或者多个队列中,消费者再去消费消息。如果路由不到,或许会返回给生产者,或许直接丢弃。
type RabbitMQ struct {
conn *amqp.Connection
// 信道
channel *amqp.Channel
// 队列名称
QueueName string
// 交换机
Exchange string
// 路由键
RoutingKey string
// 连接信息
MqUrl string
sync.Mutex
}
信道是建立在TCP连接上的虚拟连接,就是说rabbitmq在一条TCP上建立成百上千个信道来达到多个线程处理,这个TCP被多个线程共享,每个线程对应一个信道,信道在rabbit都有唯一的ID ,保证了信道私有性,对应上唯一的线程使用。(线程和信道一一对应)
交换机的作用就是类似路由器,服务器会根据路由键将消息从交换机路由到队列上去。(消息发到RabbitMQ的服务器上对应的交换机,交换机根据指定的路由键发到对应的队列上去)
直连交换机意思是此交换机需要绑定一个队列,要求该消息与一个特定的路由键完全匹配。简单点说就是一对一的,点对点的发送。(一个交换机对应一个队列进行绑定)
它会把消息路由到那些binding key与routing key完全匹配的Queue中。(队列有一个绑定key)
这种类型的交换机需要将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。很像子网广播,每台子网内的主机都获得了一份复制的消息。简单点说就是发布订阅。(交换机直接和队列进行绑定)
它会把所有发送到该Exchange的消息路由到所有与它绑定的Queue中。
主题交换机是使用通配符去匹配,路由到对应的队列。通配符有两种:"*" 、 “#”。需要注意的是通配符前面必须要加上".“符号。
*符号:有且只匹配一个词。比如 a.*可以匹配到"a.b”、“a.c”,但是匹配不了"a.b.c"。
#符号:匹配一个或多个词。比如"rabbit.#“既可以匹配到"rabbit.a.b”、“rabbit.a”,也可以匹配到"rabbit.a.b.c"。
(一个交换机可有多个路由键,一个路由键只能绑定一个交换机;一个队列只能有一个绑定路由键,即队列和路由键一对一,路由键和交换机多对一)
(生产者发消息给交换机可以带一个路由键,交换机就会根据路由键去匹配队列)
前面提到的direct规则是严格意义上的匹配,换言之Routing Key必须与Binding Key相匹配的时候才将消息传送给Queue,那么topic这个规则就是模糊匹配,可以通过通配符满足一部分规则就可以传送。
- 比较常用的就是以上三种:直连(DirectExchange),发布订阅(FanoutExchange),通配符(TopicExchange)。熟练运用这三种交换机类型,基本上可以解决大部分的业务场景。
实际上稍微思考一下,可以发现通配符(TopicExchange)这种模式其实是可以达到直连(DirectExchange)和发布订阅(FanoutExchange)这两种的效果的。
FanoutExchange不需要绑定routingKey,所以性能相对TopicExchange会好一点。
- 它跟上面三种有点区别,它的路由不是用routingKey进行路由匹配,而是在匹配请求头中所带的键值进行路由。
- 路由流程
主要就是交换机、路由键和队列三者的关系。
1.先声明一个交换机;(生产者发送到交换机)
2.生产者将队列与交换机绑定,同时绑定一个路由键,即将队列通过路由键绑在交换机上;(生产者发送消息到交换机,交换机通过路由键判断将数据送往哪个队列)
3.发送消息时,指定交换机、路由键。
- [1] 超详细的RabbitMQ入门,看这篇就够了!
- [2] Kafka、ActiveMQ、RabbitMQ、RocketMQ 区别以及高可用原理
- [3] RabbitMQ工作模式之简单模式、工作队列模式、发布订阅模式、路由模式、主题模式、RPC模式
- [4] RabbitMQ六种工作模式
- [5] RabbitMQ 路由器使用 绑定键 路由键 详解 路由器与队列绑定



