RabbitMQ-同步和异步区别&快速入门



在这里插入图片描述

1.1.同步和异步通讯

服务间通讯有同步和异步两种方式:

同步通讯:就像打电话,需要实时响应。

异步通讯:就像发邮件,不需要马上回复。

在这里插入图片描述

两种方式各有优劣,打电话可以立即得到响应,但是你却不能跟多个人同时通话。发送邮件可以同时与多个人收发邮件,但是往往响应会有延迟。

1.1.1.同步通讯

虽然调用可以实时得到结果,但存在下面的问题:

  • 耦合度高: 每次加入新的需求 都有去改代码
  • 性能下降: 调用服务等待时间长
  • 资源浪费: 调用链中的服务都要等待,不能及时的释放资源
  • 级联失败: 级联调用的时候会有级联失败的风险

1.1.2.异步通讯

异步调用则可以避免上述问题:

我们以购买商品为例,用户支付后需要调用订单服务完成订单状态修改,调用物流服务,从仓库分配响应的库存并准备发货。

在事件模式中,支付服务是事件发布者(publisher),在支付完成后只需要发布一个支付成功的事件(event),事件中带上订单id。

订单服务和物流服务是事件订阅者(Consumer),订阅支付成功的事件,监听到事件后完成自己业务即可。

为了解除事件发布者与订阅者之间的耦合,两者并不是直接通信,而是有一个中间人(Broker)。发布者发布事件到Broker,不关心谁来订阅事件。订阅者从Broker订阅事件,不关心谁发来的消息。

在这里插入图片描述

Broker 是一个像数据总线一样的东西,所有的服务要接收数据和发送数据都发到这个总线上,这个总线就像协议一样,让服务间的通讯变得标准和可控。

好处:

  • 吞吐量提升:无需等待订阅者处理完成,响应更快速

  • 故障隔离:服务没有直接调用,不存在级联失败问题

  • 调用间没有阻塞,不会造成无效的资源占用

  • 耦合度极低,每个服务都可以灵活插拔,可替换

  • 流量削峰:不管发布事件的流量波动多大,都由Broker接收,订阅者可以按照自己的速度去处理事件

缺点:

  • 架构复杂了,业务没有明显的流程线,不好管理
  • 需要依赖于Broker的可靠、安全、性能

好在现在开源软件或云平台上 Broker 的软件是非常成熟的,比较常见的一种就是我们今天要学习的MQ技术。


1.2.技术对比:

MQ,中文是消息队列(MessageQueue),字面来看就是存放消息的队列。也就是事件驱动架构中的Broker。

比较常见的MQ实现:

  • ActiveMQ
  • RabbitMQ
  • RocketMQ
  • Kafka

几种常见MQ的对比:

RabbitMQ ActiveMQ RocketMQ Kafka
公司/社区 Rabbit Apache 阿里 Apache
开发语言 Erlang(并发能力强,性能及其好) Java Java Scala&Java
协议支持 AMQP,XMPP,SMTP,STOMP OpenWire,STOMP,REST,XMPP,AMQP 自定义协议 自定义协议
可用性 一般
单机吞吐量(性能承载能力) 一般 非常高
消息延迟 微秒级 毫秒级 毫秒级 毫秒以内
消息可靠性 一般 一般

追求可用性(当需要处理数据时,资源处于可用状态的程度):Kafka、 RocketMQ 、RabbitMQ

追求可靠性:RabbitMQ、RocketMQ

追求吞吐能力(十万级别的):RocketMQ、Kafka

追求消息低延迟:RabbitMQ、Kafka

通过上述对比最后给大家建议如下:

一般的业务系统要引入 MQ,最早大家都用 ActiveMQ,但是现在确实大家用的不多了,没经过大规模吞吐量场景的验证,社区也不是很活跃,所以不推荐用这个了;

后来大家开始用 RabbitMQ,由于是 erlang 语言阻止了大量的 Java 工程师去深入研究和掌控它,对公司而言,几乎处于不可控的状态,但是确实人家是开源的,比较稳定的支持,活跃度也高;

不过现在确实越来越多的公司会去用 RocketMQ,确实很不错,毕竟是阿里出品,但社区可能有突然黄掉的风险(目前 RocketMQ 已捐给 Apache,但 GitHub 上的活跃度其实不算高)对自己公司技术实力有绝对自信的,推荐用 RocketMQ,否则回去老老实实用 RabbitMQ 吧,人家有活跃的开源社区,绝对不会黄。

所以中小型公司,技术实力较为一般,技术挑战不是特别高,用 RabbitMQ 是不错的选择;大型公司,基础架构研发实力较强,用 RocketMQ 是很好的选择。

如果是大数据领域的实时计算、日志采集等场景,用 Kafka 是业内标准的,绝对没问题,社区活跃度很高,绝对不会黄,何况几乎是全世界这个领域的事实性规范。

2.快速入门

2.1.安装RabbitMQ

MQ的基本结构:

在这里插入图片描述

在这里插入图片描述

【1】RabbitMQ中的一些角色:

  • publisher:生产者(发布者)
  • consumer:消费者
  • exchange:交换机,负责消息路由
  • queue:队列,存储消息
  • virtualHost:虚拟主机,隔离不同租户的exchange、queue、消息的隔离
  • channel:表示通道,操作MQ的工具。是消息发布者和交换机之间的连接通道,也是消息消费者连接队列的通道。

【2】将以上的RabbitMQ基本结构归纳为以下四点:

1.消息的发布者(publisher)将消息投递到交换机(exchange)

2.交换机(exchange)将消息转发到与之绑定的队列(queue)

3.消息消费者(consumer)监听队列(queue),获取队列(queue)中的消息

4.将不同的队列(queue)和交换机(exchange)划分成一组,称为虚拟主机(virtualHost)

注意:消息的发布者(publisher)只知道对应的交换机(exchange),不知道队列。反之,消息消费者(consumer)只知道队列(queue),不知道交换机(exchange)

2.2.RabbitMQ消息模型

RabbitMQ官方提供了5个不同的Demo示例,对应了不同的消息模型:

【1】基本消息队列(BasicQueue)

在这里插入图片描述

P(producer/ publisher):生产者,一个发送消息的用户应用程序。我们自己书写代码发送。

C(consumer):消费者,消费和接收有类似的意思,消费者是一个主要用来等待接收消息的用户应用程序。我们自己书写代码接收。

队列(红色区域):存在于rabbitmq内部。许多生产者可以发送消息到一个队列,许多消费者可以尝试从一个队列接收数据。

总之:生产者将消息发送到队列,消费者从队列中获取消息,队列是存储消息的缓冲区。

【2】工作消息队列(WorkQueue)

在这里插入图片描述

工作消息队列是基本消息队列的增强版,具有多个消费者消费队列的消息。假设消息队列中积压了多个消息,那么此时可以使用多个消费者来消费队列中的消息。效率要比基本消息队列模型高。

【3】发布订阅(Publish、Subscribe),又根据交换机类型不同分为三种:

1、1个生产者,多个消费者

2、每一个消费者都有自己的一个队列

3、生产者没有将消息直接发送到队列,而是发送到了交换机

4、每个队列都要绑定到交换机

5、生产者发送的消息,经过交换机到达队列,实现一个消息被多个消费者获取的目的

X(Exchanges):交换机一方面:接收生产者发送的消息。另一方面:知道如何处理消息,例如递交给某个特别队列、递交给所有队列、或是将消息丢弃。到底如何操作,取决于Exchange的类型。Exchange(交换机)只负责转发消息,不具备存储消息的能力,因此如果没有任何队列与Exchange绑定,或者没有符合路由规则的队列,那么消息会丢失!

  • Fanout Exchange:广播

在这里插入图片描述

将消息交给所有绑定到交换机的队列,生产者发送的消息,只能发送到交换机,交换机来决定要发给哪个队列,生产者无法决定。交换机把消息发送给绑定过的所有队列.队列的消费者都能拿到消息。实现一条消息被多个消费者消费.

  • Direct Exchange:路由

在这里插入图片描述

1.在广播模式中,生产者发布消息,所有消费者都可以获取所有消息。

2.在某些场景下,我们希望不同的消息被不同的队列消费。这时就要用到Direct类型的Exchange。在Direct模型下,队列与交换机的绑定,不能是任意绑定了,而是要指定一个RoutingKey(路由key).消息的发送方在向Exchange发送消息时,也必须指定消息的routing key。

3.P:生产者,向Exchange发送消息,发送消息时,会指定一个routing key。

4.X:Exchange(交换机),接收生产者的消息,然后把消息递交给 与routing key完全匹配的队列

  • Topic Exchange:主题

在这里插入图片描述

1.Topic类型的Exchange与Direct相比,都是可以根据RoutingKey把消息路由到不同的队列。只不过Topic类型Exchange可以让队列在绑定Routing key 的时候使用通配符!

2.Routingkey 一般都是有一个或多个单词组成,多个单词之间以”.”分割,例如: item.insert

3.通配符规则:

#:匹配一个或多个词

*:匹配恰好1个词


2.3.入门案例

简单队列模式的模型图:

在这里插入图片描述

官方的HelloWorld是基于最基础的消息队列模型来实现的,只包括三个角色:

  • publisher:消息发布者,将消息发送到队列queue
  • queue:消息队列,负责接受并缓存消息
  • consumer:订阅队列,处理队列中的消息

项目结构如下:

在这里插入图片描述

包括三部分:

  • mq-demo:父工程,管理项目依赖
  • publisher:消息的发送者
  • consumer:消息的消费者

2.3.1.publisher实现

略…



在这里插入图片描述



相关推荐

  1. 同步异步区别

    2024-03-22 12:54:05       27 阅读
  2. 异步同步

    2024-03-22 12:54:05       13 阅读
  3. ajax同步异步

    2024-03-22 12:54:05       15 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-03-22 12:54:05       19 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-03-22 12:54:05       19 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-03-22 12:54:05       20 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-03-22 12:54:05       20 阅读

热门阅读

  1. Node.js 常用命令

    2024-03-22 12:54:05       21 阅读
  2. 查询ECS服务启动命令包含特定的字符串

    2024-03-22 12:54:05       19 阅读
  3. 【蓝桥杯常考题型汇总】

    2024-03-22 12:54:05       21 阅读
  4. QT(19)-QNetworkRequest

    2024-03-22 12:54:05       21 阅读
  5. docker基础(四)之docker run(第一弹)

    2024-03-22 12:54:05       19 阅读
  6. Ubuntu下搭建UEFI下PXE服务端(详细)总结

    2024-03-22 12:54:05       19 阅读