消息队列学习 -- RabbitMQ概念了解

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/ydm19891101/article/details/90740426

从这篇文章开始,我们将依次介绍RabbitMQ、ActiveMQ、Kafka、RocketMQ四大主流中间件,并基于PHP语言给出demo(RocketMQ不支持PHP语言)。先从RabbitMQ开始。

一、简介

  RabbitMQ是Erlang语言开发的基于AMQP标准的开源实现,具有以下特点:

  • 保证可靠性。使用一些机制保证可靠性,如持久化、传输确认、发布确认等
  • 具有灵活的路由功能。在RabbitMQ Server中定义了很多的队列,而这些队列是与具体的key关联的。而消息具体放到哪个队列中,是通过Exchange(交换器)来读取Binding(存储的是路由键和消息队列的映射关系)路由的。生产者发送的消息体内包含一个路由键、消息优先级、是否需要持久化等参数;
  • 支持消息集群。多台Broker服务器可以组成一个集群,形成一个逻辑Broker
  • 具有高可用性。通过集群实现的
  • 支持多种语言的客户端,如Java、PHP、Python
  • 提供插件机制,扩展性好
  • 提供跟踪机制,可以跟踪消息传递过程中的那个环节出现了问题

二、架构图

上面有几个关键的项:Productor、Rabbit Server、Exchange、Binding、Quene、Consumer

Productor:消息生产者,用于生产消息,并将消息发送到Exchange(实际中可能是通过Proxy实现的)。

Rabbit Server:消息队列服务器,进行消息的接收、存储以及转发

Exchange:交换器,负责进行消息的路由

Binding:存储路由规则,Exchange便是根据这个规则将消息放到某个具体的队列中的

Consumer:消息消费者,采用拉取/推送方式接收消息并进行业务逻辑处理

另外,生产者和消费者与Rabbit Server的通信都是基于TCP链接的通道(channel)实现的。

上面我们是从宏观上看的,其实,对于Rabbit Server,其内部又划分为了多个虚拟主机(vhost)。虚拟主机可以理解我一个微小版的RabbitMQ服务器,其内部具有完整的Exchange、队列、Binding;生产者通过channel与RabbtiMQ建立通信时需要指定vhost;

扫描二维码关注公众号,回复: 7192006 查看本文章

vhost是一个比较巧妙的设计,通过虚拟主机做到了逻辑上的隔离。通过为不同的应用指定不同的vhost,保证了应用程序的安全访问。

另外,交换器类型有Direct、Topic、Fanout三大类型,区别如下:

  • Direct:完全匹配、单播模式。只有消息的路由键和队列的路由键完全匹配时才会转发到该队列中;

  • Fanout:类似于广播,不关系路由键,将消息发送给绑定到交换器的每一个队列;

  • Topic:匹配模式,只有消息的路由键和队列的键匹配时才可以,上面两类型的结合;

三、应用场景

前面的一篇文章我们概述过消息队列的应用场景,有异步处理、应用解耦、分布式事务、日志收集等等。那RabbitMQ的应用场景又具体有哪些呢?

1、消息推送

好的消息推送可以提升DAU以及用户留存率,如果再可以基于用户画像做到个性化推送,那就更美了。

RabbitMQ的消息推送应用场景这主要得益于其良好的扩展性,而且Html5定义了WebSocket,可以实现服务器与客户端之间的全双工通信。通过全双工通信,服务器就可以主动传输数据给客户端。

具体可参考:关于WebSocket+RabbitMQ整合实现消息实时推送的案例

2、异步处理/流量削峰

这个就不用说了,所有的消息队列都具有的功能。

四、其他

 文章刚开始我们说了,RabbitMQ具有高可用性,保证可靠,具体就是消息的持久化以及传输确认等,下面我们就来具体看一下。

1、持久化

        RabbitMQ对于接收到的消息可以保存到内存中以及磁盘上。其中,写入磁盘的好处是即使系统发生意外宕机,消息也不回丢失;而写入RAM的消息数据会在系统宕机时丢失。可以在发送消息时通过参数显示指定将消息持久化;

      对于可靠性要求比较高的场景,建议将消息保存到磁盘上。

2、发送消息确认

    这主要是为了解决生产者发送消息之后并不知道消息是否成功发送到Broker以及Broker是否存储成功,由于网络的复杂性,消息是有可能丢失的;

    我们上面说的持久化并不能保证消息一定就发送成功(Broker在将消息持久化时发生了宕机)。为此,RabbitMQ提供了两种解决方案:一是通过AMQP中的事务机制,二是把信道(channel)设置为确认模式。

   对于事务模式,需要生产者同步等待Broker的返回结果,在性能上会极大地降低吞吐量,解决方案偏重,不建议使用;

   对于确认模式,其最大的好处是异步,生产者在发送完一条消息之后便可继续发送下一条消息,当生产者收到确认消息后调用回掉函数处理。这种方式比较轻,对Broker的性能影响也比较小。

3、消费消息确认

  上面的发送消息确认保证消息放到了Broker中,但是,很多时候生产者还需要关注消息是否成功到达消费者服务器,或者是否被消费者成功消费。

实际中,可能出现消费者成功接收到了消息,但在消费消息的时候发生了系统宕机,这个时候消息就丢失了。也有可能Broker在推送一条消息之后,由于网络不稳定,消息在网络中迷失了。

为了避免上述两种情况,需要进行消费者回执:消费者在消费完消息之后发送一个回执给RabbitMQ服务器,RabbitMQ在收到回执消息之后再将消息从队列中删除。如果在规定的超时时间内没有收到回执,认为消息丢失了,会重新发送消息;如果未收到回执而且未收到回执而且消费者与RabbitMQ服务器的信道(消费者服务器宕机)断开了,RabbitMQ会将消息发送给其他消费者进行处理(如果有其他消费者)。

有两种消息回执模式:自动回执、手动回执;

自动回执:当Broker成功将消息发送给消费者之后变会立即将此消息从消息队列中删除;

自动回执:只有收到消费者的ACK确认消息之后才会删除;

具体回执模式可以在消费者与Broker建立信道时指定。

猜你喜欢

转载自blog.csdn.net/ydm19891101/article/details/90740426