RabbitMQ--基础--01--介绍

RabbitMQ–基础–01–介绍


1、介绍

  1. 是一套开源(MPL)的消息队列服务软件
  2. 是由 LShift 提供的一个 Advanced Message Queuing Protocol (AMQP) 的开源实现
  3. 由以高性能、健壮以及可伸缩性出名的 Erlang 写成。
  4. 官网:https://www.rabbitmq.com/

2、AMQP 是什么?

  1. 高级消息队列协议,它使得遵从该规范的客户端应用和消息中间件服务器的全功能互操作成为可能
  2. 客户端应用可以通过这个协议与消息代理和它实现的 AMQP 模型进行交互通信

2.1、实现原理图

在这里插入图片描述

3、MQ 是什么?

  1. 全称 Message Queue , 即消息队列
  2. 是一种跨进程、异步的通信机制
  3. 用于上下游传递消息,由消息系统来确保消息的可靠传递。
  4. 开源、性能优秀,稳定性保障
  5. 提供可靠性消息投递模式、返回模式
  6. 与Spring AMQP完美整合,API丰富
  7. 集群模式丰富,表达式配置,HA模式,镜像队列模型
  8. 保证数据不丢失的前提做到高可靠性、可用性

3.1、优点

3.1.1、异步通信

将以前不必要的同步操作,优化成异步操作,提高性能

3.1.1.1、举例

如图所示。一个客户端请求发送进来,系统A会调用系统B、C、D三个系统,同步请求的话,响应时间就是系统A、B、C、D的总和,也就是800ms。如果使用MQ,系统A发送数据到MQ,然后就可以返回响应给客户端,不需要再等待系统B、C、D的响应,可以大大地提高性能。对于一些非必要的业务,比如发送短信,发送邮件等等,就可以采用MQ。

在这里插入图片描述

如图所示。这其实是MQ一个很重要的应用。假设系统A在某一段时间请求数暴增,有5000个请求发送过来,系统A这时就会发送5000条SQL进入MySQL进行执行,MySQL对于如此庞大的请求当然处理不过来,MySQL就会崩溃,导致系统瘫痪。如果使用MQ,系统A不再是直接发送SQL到数据库,而是把数据发送到MQ,MQ短时间积压数据是可以接受的,然后由消费者每次拉取2000条进行处理,防止在请求峰值时期大量的请求直接发送到MySQL导致系统崩溃。

在这里插入图片描述

3.1.2、系统解耦

  1. 将原有A模块直接调用B模块的接口,优化成,A模块的请求给到MQ,A模块的事情就做完了
  2. MQ会主动推给B模块,或者B模块自己来拉
3.1.2.1、举例

如图所示。假设有系统B、C、D都需要系统A的数据,于是系统A调用三个方法发送数据到B、C、D。这时,系统D不需要了,那就需要在系统A把相关的代码删掉。假设这时有个新的系统E需要数据,这时系统A又要增加调用系统E的代码。为了降低这种强耦合,就可以使用MQ,系统A只需要把数据发送到MQ,其他系统如果需要数据,则从MQ中获取即可。

在这里插入图片描述

3.1.3、流量削峰

当某一时间大量的流量打到服务器上,服务器一时间无法承受,会宕机

这个时候,若请求都是从MQ队列里面出来,则能够保证这种大流量的情况下,服务器仍然能够有序的稳定的处理请求

3.1.4、日志处理

3.2、缺点

  1. 系统可用性降低,对外部有依赖了
  2. 需要考虑 MQ 消息丢失,重复消费的问题
  3. 需要花费精力保证消息的顺序性,一致性

3.3、MQ 如何避免消息堆积

  1. 提高消费速率(集群的方式)
  2. 消费者批量获取消息进行消费

3.4、MQ 如何避免消费者重复消费(幂等性问题)

  1. 全局ID(增加标志位) + 保证业务一致性

3.5、MQ 如何保证消息不丢失

  1. 消息确认机制
  2. 持久化
  3. 消息 ACK

3.6、MQ 如何保证消息顺序一致性

绑定同一个消费者和队列

3.7、MQ 推与拉取架构模型是怎么样的?

  1. MQ服务器与消费者建立长连接后,MQ服务器会主动推数据给到消费者
  2. 当消费者第一次启动的时候,会去找MQ服务器拉数据

3.9、MQ 有哪些消费模式

3.9.1、推模式

注册一个消费者后,RabbitMQ会在消息可用时,自动将消息进行推送给消费者。这种方式效率最高最及时。

3.9.2、拉模式

属于一种轮询模型,发送一次get请求,获得一个消息。如果此时RabbitMQ中没有消息,会获得一个表示空的回复。

3.9.3、自动确认

消费者消费消息的时候,将自动向RabbitMQ进行确认。

3.9.4、手动确认

消费者消费消息的时候,手动调用相应函数进行ack应答

3.9.5、qos预取模式

  1. 在确认消息被接收之前,消费者可以预先要求接收一定数量的消息,在处理完一定数量的消息后,批量进行确认

当然,如果消费者应用程序在确认消息之前崩溃,则所有未确认的消息将被重新发送给其他消费者

4、RabbitMQ 使用场景

  1. 错峰流控
  2. 保证数据的最终一致性
  3. 生产者和消费者业务解耦
  4. 服务间异步通信
  5. 定时任务
  6. 顺序消费

5、RabbitMQ 的特点

5.1、可靠性

使用了 持久化、传输确认、发布确认 等 机制来保证可靠性

5.2、灵活的路由

  1. 在消息进入队列之前,通过Exchange来路由消息
  2. 对于典型的路由功能,RabbitMQ 已经提供了一些内置的Exchange来实现
  3. 对于复杂的路由功能,RabbitMQ 可以将多个Exchange绑定在一起,也通过插件机制实现自己的Exchange

5.3、消息集群

  1. 多个 RabbitMQ 服务器可以组成一个集群,形成一个逻辑 Broker
  2. 可以根据实际业务情况动态地扩展集群中节点

5.4、高可用

RabbitMQ 队列可以在集群中的机器上进行镜像,使得在部分节点出问题的情况下队列仍然可用

5.5、多种语言客户端

RabbitMQ 几乎支持所有常用语言,比如 GO、 Java、 Python、 Ruby、 PHP等

5.6、管理界面

RabbitMQ 提供了一个易用的用户界面,使得用户可以监控和管理消息、集群中的节点等

5.7、跟踪机制

如果消息异常,RabbitMQ 提供了消息的跟踪机制,使用者可以找出具体发生了什么

5.8、插件机制

RabbitMQ 提供了许多插件,以实现从多方面进行扩展,当然也可以编写自己的插件

5.9、支持的协议多

RabbitMQ 除了原生支持 AMQP 协议,还支持 STOMP, MQTT等多种消息中间件协议

6、消息确认机制

6.1、问题

在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机的情况,这种情况下就可能会导致消息丢失。

6.2、期望

为了避免这种情况发生,我们可以要求消费者在消费完消息后发送一个回执给RabbitMQ
1. RabbitMQ收到消息回执(Message acknowledgment)后才将该消息从Queue中移除。
2. RabbitMQ没有收到消息回执并检测到消费者的RabbitMQ连接断开,则RabbitMQ会将该消息发送给其他消费者(如果存在多个消费者)进行处理

6.3、消息回执引发的问题

如果我们的开发人员在处理完业务逻辑后,忘记发送回执给RabbitMQ,这将会导致严重的问题,Queue中堆积的消息会越来越多,消费者重启后会重复消费这些消息并重复执行业务逻辑

7、消息持久化机制

保证RabbitMQ服务重启的情况下,也不会丢失消息。

7.1、方案

  1. 设置Queue持久化(durable)
  2. 设置Message持久化(durable)

7.2、上面方案的缺陷

上面方案依然有小概率丢失事件的发生,比如以下场景

RabbitMQ服务器已经接收到生产者的消息,但还没来得及持久化该消息时RabbitMQ服务器就断电了

要想解决这个问题,那么我们要用到事务。

8、事务

8.1、使用事务步骤

  1. 消费者 通过txSelect()开启一个事务
  2. 消费者 发送消息给服务器
  3. 消费者 通过txCommit()提交该事务
    1. 如果txCommit()提交成功,则该消息一定会持久化。
    2. 如果txCommit()提交失败,则该消息不会被服务器接收。
      1. 消费者 通过txRollback()命令用于回滚某一个事务。

9、消息分发机制

9.1、场景

消费者 消费消息的速度 跟不上 生产者,导致消息堆积。

9.2、解决方案

  1. 使用工作队列,一个队列有多个消费者同时消费数据。
  2. 工作队列有两种分发数据的方式
    1. 轮询分发(Round-robin)
    2. 公平分发(Fair dispatch)

轮询分发(Round-robin)和 公平分发(Fair dispatch)。轮询分发:队列给每一个消费者发送数量一样的数据。公平分发:消费者设置每次从队列中取一条数据,并且消费完后手动应答,继续从队列取下一个数据。

9.3、轮询分发

  1. 工作队列给每一个消费者发送数量一样的数据,并不会因为消费者处理数据速度不一样使得消费者取得不一样数量的数据。
  2. 轮询分发有一些隐患
    1. 消费者虽然得到了消息,但是如果消费者没能成功处理业务逻辑,在RabbitMQ中也不存在这条消息。y也就是出现消息丢失并且业务逻辑没能成功处理的情况。

9.4、公平分发

  1. 消费者设置每次从队列中取一条数据,并且关闭自动回复机制,每次取完一条数据后,手动回复并继续取下一条数据。
  2. 与轮询分发不同的是,当每个消费都设置了每次只会从队列取一条数据时,并且关闭自动应答,在每次处理完数据后手动给队列发送确认收到数据。这样队列就会公平给每个消息费者发送数据,消费一条再发第二条,而且可以在管理界面中看到数据是一条条随着消费者消费完从而减少的,并不是一下子全部分发完了。
  3. 采用公平分发方式就不会出现消息丢失并且业务逻辑没能成功处理的情况。

10、RabbitMQ和kafka对比

10.1、消费方式

  1. RabbitMQ在吞吐量方面略有逊色,但支持更多的消息队列功能。
  2. Kafka采用拉取(Pull)方式消费消息,吞吐量相对更高,适用于海量数据收集与传递场景,例如日志采集和集中分析。

10.2、性能

消息中间件的性能主要衡量吞吐量,Kafka的吞吐量比RabbitMQ要高出1~2个数量级,RabbitMQ的单机QPS在万级别,Kafka的单机QPS能够达到百万级别。

RabbitMQ单机写入TPS单实例约7万条/秒,单机部署3个Broker,可以跑到最高12万条/秒,消息大小10个字节,Kafka如果开启幂等、事务等功能,性能也会有所降低。

10.3、数据可靠性

Kafka与RabbitMQ都具备多副本机制,数据可靠性较高。
RabbitMQ支持异步实时刷盘,同步刷盘,同步Replication,异步Replication。

10.4、服务可用性

Kafka采用集群部署,分区与多副本的设计,使得单节点宕机对服务无影响,且支持消息容量的线性提升。

RabbitMQ支持集群部署,集群节点数量有多种规格。RabbitMQ是分布式架构,可用性高。

10.5、功能

Kafka与RabbitMQ都是比较主流的两款消息中间件,具备消息传递的基本功能,但在一些特殊的功能方面存在差异,RabbitMQ在阿里集团内部有大量的应用在使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值