rabbitMQ重点篇
- 各种MQ的比较
- | 服务性能 | 数据存储 | 集群架构 | API和社区 |
---|---|---|---|---|
ActiveMQ | 中等吞吐量 | KahaDB、MySQL等等 | Master-Slave模式 network模式 |
丰富 |
Kafaka | 高吞吐量 没有事务 对消息丢失、重复消费、消息错误都没有要求 |
内存 | ZK模式 | - |
rocketMQ | 高吞吐量 高性能 有事务,消息可靠 |
- | 可多主多从 | 半开源 |
rabbitMQ | 高吞吐量 数据可靠,安全 稳定性好 |
磁盘或内存 | HA+镜像队列等多种 | 开源 |
-
rabbitMQ的优点?
答:跨平台跨语言,开源,可靠性投递,返回模式,与spring的整合很好,集群模式丰富。 -
rabbitMQ的高能是如何做到的?
答:其底层的Erlang语言有着和原生socket一样好的延迟。 -
什么是AMQP?
答:Advanced Message Queuing Protocol,高级消息队列协议。
是具有现代特征的二进制协议。是应用层协议的一个开放标准,为面向消息的中间件设计。 -
AMQP的核心是什么?
- Server:又称Broker,用于接收客户端的连接;
- Connection:连接,应用程序与broker的连接;
- Channel:网络信道,消息读写的通道;
- Message:消息,服务器与应用程序之间传送的数据;有Properties和Body组成,Properties可以对消息进行修饰(比如优先级,延迟等),Body是消息的主体。
- Virtual Host:虚拟地址,用于进行逻辑隔离,是最上层的消息路由。
- Exchange:交换机,接收消息,根据路由键转发消息到绑定队列。
- Binding:Exchange和Queue之间的虚拟连接,binding中可以包含routing key。
- Routing Key:一个路由规则,虚拟机可以用他来确定如何路由一个特定消息;
- Queue:也称Message Queue,消息队列,保存消息并将它们转发给消费者。
-
rabbitMQ的整体架构是什么样的?
image.png -
rabbitMQ的交换exchange类型有哪些?
- direct:直接匹配;所有发送到direct exchange的消息都会被转发到routing key中指定的queue;routing key必须完全匹配,否则会被放弃。
- topic:模糊匹配;Exchange将routing key和topic模糊匹配;#是1~N个单词,*匹配一个单词。
- fanout:扇形匹配;不处理routing key,直接将队列绑定到交换机上;最快,被绑定的队列都会接收到该消息。
- headers:不常用。
-
rabbitMQ的持久化是怎么做的?
答:其exchange、queue都有一个字段(durability)为true则表示要持久化。表示在重启之后,exchange和queue会重新建立。
而delivery_mode才是真正的消息数据持久化到磁盘,为2表示持久化,为1表示非持久化。 -
消息如何做到100%投递?
答: 1)消息落库,对消息进行打标(改变状态);(broker应答之后);
2)消息的延迟投递,做二次检查,回调检查。 -
消息的幂等性投递。
答:幂等性,就是同一条消息无论经过多少次投递,所得结果都是一样的。 -
重复消费消息。
答:对于指定消息的业务关键字ID, -
confirm、return消息机制。
答:
以下两个机制都是在设置了之后才有效:
confirm机制:在消息到达mq broker后,会给生产者一个应答;
return消息机制:在消息无法被exchange、queue、routing key接收时,会在该处提示。 -
消息的ACK与重回队列。
答:每一条消息在消费成功后,都会返回一个ack标志;而消费失败的会返回nack标志。
在nack时,可以选择重回队列。
ps:重回队列和消息限流注意数量的限制,如果限流为1个,则该队列会一直消费该消息,直到该消息成功。
一般不建议使用重回队列。假如只有一条消息,该消息一直消费失败,则会造成死循环。 -
消息限流。
消息限流,就是有大量的消息到消费者端,超出了消费者承受的能力,所以需要对消息数量进行限制,以便于消费者端正常的运行。
rabbitMQ提供了qos(服务质量保证)功能,即在非自动确认(autoack=false)的前提下,如果一定数量的消息没有被消费,则不处理新的消息。 -
TTL。
答:Time-To-Live,也就是生存时间。
设置该属性,则消息到期后,该消息会到死信队列中。 -
死信队列。
答:当一个消息没有任何消费者消费时,该消息成为死信。
进入死信队列的情况:
1)消息被拒绝或者nack时,且requeue为false;
2)消息TTL过期;
3)队列达到最大长度(超过队列长度队首消息直接进入死信)。
死信队列有自己的exchange,queue,routing key。和正常的队列是一样的。在定义正常的业务队列时,有一个参数arguments(类型为map),如下设置可以发送到死信队列:
//后面的参数为死信队列的exchange
arguments.put("x-dead-letter-exchange","dlx.exchange");
死信队列的routing key一般设置为#。