RabbitMq原理及应用

一、简介

MQ(Message Queue),即消息队列,是一种实现应用级别之间的通信手段。不同应用之间可以通过读写消息,以消息为媒介传递应用数据,不需要应用之间建立强连接。此方式与远程调用(RPC)是应用通信的常见方式。在这个调用过程中,消息发送者定义为生产者,消息接收者为消费者。

RabbitMq是使用Erlang语言开发的基于AMQP协议实现,面向消息、队列、路由的开源消息中间件。在一些企业级应用中对数据一致性、稳定性和可靠性以及吞吐量、性能要求比较高的场景应用比较广泛。

RabbitMq使用链路原理图:

RabbitMq原理及应用_第1张图片

二、RabbitMq原理

RabbitMq相比于其他MQ引入了交换器(Exchange)的概念,生产者将消息发送到Exchange,由Exchange根据调度策略路由到消息队列中,Exchange本身并不存储消息。

  1. Exchange调度策略

    1)Fanout(订阅模式/广播模式)

     

    RabbitMq原理及应用_第2张图片

Fanout交换器会把所有该交换器接收到的消息路由到所有与交换器绑定的队列中,与具体的绑定关系无关。类似于广播,在能够接收到声音的范围内都能收听到广播消息,是一对多的关系。

    2)Direct(路由模式)

     

RabbitMq原理及应用_第3张图片

Direct交换器模式要求消息携带的RoutingKey与交换器和队列的BindingKey完全匹配,匹配成功则将消息发送到对应队列,该模式也是RebbitMq的默认模式,有时候我们感觉不需要交换器也可以接收和发送消息,是因为使用了这个默认模式,该模式交换器名字是空字符串,绑定了所有的Queue(BindingKey = 队列名)。     

      3)Topic模式(通配符模式)

      

RabbitMq原理及应用_第4张图片

Topic交换器采用通配符的方式要求消息队列携带的RoutingKey和BindingKey匹配成功才能将消息发送到队列。RoutingKey要求必须是以”.“作为分隔符,”#“能够模糊匹配"."一个分隔符以内的字符,”*“能够匹配多个分隔符以内的字符。

2.消息确认机制

在实际使用过程中,会有消费者宕机未消费消息的情况,RabbitMq的解决方案是ack模式,要求消费者消费完成后向RabbitMq发送一个回执信号,RabbitMq收到这个回执以后将消息从消息队列中移除。如果RabbitMq没有收到这个回执或者消费者与RabbitMq断开连接,则RabbitMq会把消息发送到其他消费者。同时如果RabbitMq一直没有收到回执,队列中的数据会逐渐堆积。相反的,如果返回no-ack回执,每次消费者接收到消息后,RabbitMq不管是否已经消费,立即将该消息标记为已消费,从队列中移除。

3.消息持久化机制

为了防止消息丢失,可以设置RabbitMq队列消息持久化,这样可以保证大部分消息不会丢失。当然在消息还未完全持久化完成的这个过程如果RabbitMq宕机也会使部分未持久化的消息丢失。

3.事务

AMQP协议支持事务,因此RabbitMq也支持事务,RabbitMq宕机造成的数据丢失生产者是无法感知到的,因此对RabbitMq开启事务之后,只有在txCommit()之后才代表消息已经持久化。

4.消息分发机制

RabbitMq可以设置每个消费者固定消费一定数量的消息,可以在RabbitMq服务器界面中看到队列中的消息有没有被消费。

二、应用

  1. 解耦,为面向服务的架构(SOA)提供基本的最终一致性实现

传统模式的RPC调用,上下游系统之间直接调用,如果库存系统宕机,生产者者系统业务操作也会相应失败,即系统之间耦合性太重。

RabbitMq原理及应用_第5张图片

   引入消息队列,生产者系统先将数据写入消息队列,消息队列返回写入成      功,库存系统采用订阅的方式从消息队列中获取消息持久化,即便库存系      统宕机或者异常,消息队列中的消息依旧存在,等系统恢复以后继续消          费,既保持了数据的完整性也保证了系统的最终一致性。

RabbitMq原理及应用_第6张图片

2.提高数据处理效率

  

RabbitMq原理及应用_第7张图片

RabbitMq原理及应用_第8张图片

3.流量削峰

在传统模式中用户请求直接到达数据库的方式可以应对流量较小的情况,一旦用户请求到达一定的数量级,数据库压力过大就会导致宕机。

RabbitMq原理及应用_第9张图片

引入消息队列后

RabbitMq原理及应用_第10张图片

由于MQ能够处理大数据量的特点,用户高并发请求均写入消息队列,消费者可以按照某个固定值从消息队列消费请求,即便消费数据需要一定的时间,但是并且不影响数据的最终一致性。

一、消息队列的优缺点

优点:解耦、效率、削峰

缺点:

1)系统的可用性降低,

引入消息队列以后系统的外部依赖增多,如果MQ挂了之后会导致整个生态崩溃,这个时候可能就要考虑MQ集群等。

2)系统复杂度提高

随着系统复杂度的提高,相应的问题自然就会增多,比如消息会不会重复消费,如何保证消息的完整性,如果保证消息的消费顺序等。

3)一致性问题

如果在整个链路过程中数据丢失,会导致数据的不一致性。

总结,消息队列是一种比较复杂的架构,只有在合适的业务场景中使用才能够做到物尽其用,否则反而造成系统过于臃肿,MQ带来的问题需要额外的考虑技术方案解决,当然,在一些特殊场景,MQ则是最优解。

你可能感兴趣的:(java)