RabbitMQ

Posted 奔跑匠人

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RabbitMQ相关的知识,希望对你有一定的参考价值。

1 RabbitMQ工作原理

2 RabbitMQ六种工作模式

2.1 simple简单模式

一个队列中,一条消息只能被一个消费者消费;

2.2 work工作模式

一个生产者,多个消费者,每个消费者获取到的消息唯一;

2.3 Router路由模式

消息需要制定direct类型的exchange和RoutingKey, 将消息发送到routingkey全匹配的队列;

2.4 Topic主题模式

消息需要制定topic类型的exchange和RoutingKey, 将消息发送到routingkey模糊匹配的队列;

2.5 Fanout发布订阅模式

消息需要制定fanout类型的exchange, 消息发送到该交换机的所有队列中;

2.6 Header模式

消息需要制定header类型的exchange,根据发送的消息内容中的headers属性进行匹配。

3 RabbitMQ部署方案

3.1 单节点模式

最简单的情况,非集群模式,节点挂了,消息就不能用了。业务可能瘫痪,只能等待。

3.2 普通模式

默认的集群模式,某个节点挂了,该节点上的消息不能用,有影响的业务瘫痪,只能等待节点恢复重启可用(必须持久化消息情况下)。

3.3 镜像模式

把需要的队列做成镜像队列,存在于多个节点,属于RabbitMQ的HA方案;
为什么设置镜像模式集群,因为队列的内容仅仅存在某一个节点上面,不会存在所有节点上面,所有节点仅仅存放消息结构和元数据。

如果想解决上面途中问题,保证消息不丢失,需要采用HA 镜像模式队列。
下面介绍下三种HA策略模式
1)同步至所有的;
2)同步最多N个机器;
3)只同步至符合指定名称的nodes。

缺陷:所有的读写都是在master上进行,从节点只是备份,最终会路由到master进行处理。

4 RabbitMQ如何保证消息不丢失

4.1 丢失消息的3种场景

4.2 解决方案

  1. 发送消息开启confirm模式,MQ收到消息后异步通知生产者,消息发送成功。
  2. 消息持久化:
    • .Exchange 设置持久化:durable = true
    • Queue 设置持久化:durable = true
    • Message持久化发送:发送消息设置发送模式deliveryMode=2,代表持久化消息。
  3. 镜像集群部署模式。
  4. 手动ACK:使用Message acknowledgment 机制,就是消费端消费完成要通知服务端,服务端才把消息从内存删除。

这样就解决了,即使一个消费者出了问题,没有同步消息给服务端,还有其他的消费端去消费,保证了消息不丢。

5 如何保证顺序消费

  • 设置每次只取一条消息:perfach_count=1
  • 设置消费者为1:consumer=1,max_consumer=1
  • 设置首次声明它的连接可见:exclusive = true
    • 针对连接可见,只要是当前connection下的信道都可以访问
    • 一旦该队列被声明,其他连接无法声明相同名称的排他队列。
    • 队列即使显示声明为durable,连接断开时(注意不是信道断开)也会被自动删除。

6 如何提高队列的消费速度

降低生产速度:往往跟业务相关。
提高消费速度:批量操作,减少重复查询,SQL优化。
支持并发消费:设置多个并发消费者或者增加服务节点。
拆分任务队列:大任务,拆分几个小任务并发消费。

7 和kafaka的区别

  • 语言不同:RabbitMQ是erlanng语言开发,kafka是cala语言开发。
  • 结构不同:RabbitMQ采用AMQP(Advanced Message Queuing Protocol,高级消息队列协议)是一个进程间传递异步消息的网络协议,kafka采用mq结构:broker 有part 分区的概念。
  • Broker与Consume交互方式不同:RabbitMQ 采用push的方式,kafka采用pull的方式。
  • 在集群负载均衡方面:rabbitMQ的负载均衡需要单独的loadbalancer进行支持,kafka采用zookeeper对集群中的broker、consumer进行管理。
  • 使用场景:rabbitMQ支持对消息的可靠的传递,支持事务,不支持批量的操作;基于存储的可靠性的要求存储可以采用内存或者硬盘,金融场景中经常使用。kafka具有高的吞吐量,内部采用消息的批量处理,zero-copy机制,数据的存储和获取是本地磁盘顺序批量操作,具有O(1)的复杂度(与分区上的存储大小无关),消息处理的效率很高。(大数据)

8 延迟队列的实现

8.1 采用死信队列

  • 相同延迟时间的任务放一个队列。不同延迟时间的分开多个任务队列。
  • 不同延迟时间的任务都放一个队列。有可能导致到时间了还没消费的情况。

8.2 采用插件的方式

收到消息后并未立即把消息投递到目标队列,而是存储在一个mnesia(分布式数据库中)中,随后检查消息延迟时间,到达可投递时间,将其通过x-delayed-type类型标记的交换机投递到目标队列。

以上是关于RabbitMQ的主要内容,如果未能解决你的问题,请参考以下文章

RabbitMQ—SpringBoot中实现死信队列

RabbitMQ的死信队列和延时队列

RabbitMQ 中的死信死信消息

RabbitMQ--死信队列/延迟队列--使用/原理

RabbitMQ 死信队列

RabbitMQ实战-死信队列