Rabbitmq入门级基础概念原理介绍

Rabbitmq特点

  1. 低延时
  2. 基于AMQP协议,支持主流开发语言接入,支持主流操作系统
  3. 开源,Erlang开发,天然支持分布式扩展,不需要像ActiveMQ、Kafka那样通过ZooKeeper分别来实现HA方案和保存集群的元数据
  4. 开箱即用,上手方便
  5. 社区活跃,文档完善,错误解决方便
  6. 高并发性能好

术语概念

术语概念
Server(Broker)消息队列服务器端,用于接收客户端发送来的消息以及向客户端推送消息
ClientProducer消息队列服务器端,用于向服务器端发送消息
ClientConsumer消息队列客户端,用于接收服务器端转发的消息
VirtualHost虚拟主机,一个VirtualHost可以包含多个Exchange和Queue,用于不同的环境隔离
Exchange消息队列交换机,在服务器端用于将收到的消息按照规则路由至其下的不同队列中,交换机不存储消息
ExchangeType消息队列交换机类型: Fanout、Direct、Topic、Headers.其规定了交换机路由方式
BindingKey绑定关键字,将Exchange和Queue关联绑定属性
Queue消息队列用于存储未被消费者消费的消息
Message由Header和body组成,body是真正需要发送的数据内容.header存储该消息投递信息

工作模式

如果消息发送到没有队列绑定的交换机上,那么消息将丢失

工作队列模式(WorkQueues)

一个生产者发送消息至一个队列,1个/多个消费者从队列中依次消费消息(不重复消费)
无需定义交换机,只需向队列直接发送消息即可(没有指定交换机,消息将发送给默认交换机,队列不指定交换机也会绑定那个默认的交换机)
多个消费者监听同一个队列
一条消息只会被其中一个消费者消费
消费者处理完一条消息才会收到下一条消息.消费速度快的消费者可以多消费,慢的可以少消费.自带负载均衡.
适合执行异步的资源密集型任务,多个消费者同时工作提高消费速度

发布订阅模式(Plublish/Subscribe)

该模式要求交换机类型为Fanout
生产者发送消息至交换机,交换机会将该消息投递至其下的所有队列上即广播
适用场景: 商品下单成功可以将该消息投递出去使发送成功下单短信、商品库存修改等无需同步执行的功能一起执行

路由模式(Routing)

该模式交换机类型为Direct
队列绑定至交换机时需要设置RoutingKey(可以绑定多个RoutingKey)
生产者发送消息至交换机并指定其RoutingKey,交换机会将消息投递至其下与该RoutingKey设置相同的队列上

通配符模式(Topics)

该模式交换机类型为Topic. 和路由模式类似,只不过该模式RoutingKey支持通配符匹配(定向广播)
符号#:匹配一个或者多个词lazy.# 可以匹配lazy.irs或者lazy.irs.cor
符号*:只能匹配一个词lazy.* 可以匹配lazy.irs或者lazy.cor
队列绑定至交换机时需要设置RoutingKey(可以绑定多个RoutingKey)
生产者发送消息至交换机并指定Routingkey,交换机会将消息投递至其下绑定RoutingKey规则符合的队列上
可实现Routing和Publish/Subscribe模式

Header模式

与Routing模式类似,只不过其取消RoutingKey替换为使用Header中的key/value来进行队列匹配

RPC模式


RPC即客户端远程调用服务端的方法 ,使用MQ可以实现RPC的异步调用,基于Direct交换机实现

  1. 每个客户端即是生产者也是消费者,向RPC请求队列发送RPC调用消息,同时监听RPC响应队列
  2. 服务端监听RPC请求队列的消息,收到消息后执行服务端的方法,得到方法返回的结果
  3. 服务端将RPC方法 的结果发送到RPC响应队列
  4. 客户端(RPC调用方)监听RPC响应队列,接收到RPC调用结果

消息确认机制(可靠消费)

已经在transaction事务模式的channel是不能再设置成confirm模式的,即这两种模式是不能共存的

AMQP事务模式(仅作了解)

事务相关方法:

  1. channel.txSelect()设置通道为事务模式
  2. channel.txCommit()提交事务
  3. channel.txRollback()回滚事务

使用事务确认机制则会增加事务信息步骤如下

client发送Tx.Select
broker发送Tx.Select-Ok(之后publish)
client发送Tx.Commit
broker发送Tx.Commit-Ok

缺点:

使用AMQP事务确认机制,会增加消费时延从而降低了消息队列性能

Confirm(ack)模式(推荐使用)

JavaAPI解释参考
生产者端(消息发送确认):
发送确认分为两步,一是是否到达交换器,二是是否到达队列

  1. 生产者通过调用channel的confirmSelect方法将channel设置为confirm模式
  2. 开启confirm模式的信道发布的消息会被指定一个唯一ID.当该消息投递到队列后,broker会发送确认信息(包含该ID)给生产者(如果该队列持久化,则确认信息会在写入磁盘后发出)
  3. broker也可以设置basic.ack的multiple域,表示到这个序列号之前的所有消息都已经得到了处理
  4. confirm模式是异步的,不会妨碍生产者等待确认时的其他消息发送.
  5. 如果RabbitMQ因为自身内部错误导致消息丢失,就会发送一条nack消息,生产者应用程序同样可以在回调方法中处理该nack消息
  6. 同一条消息不会既被confirm(ack)又被nack,单一定会被confirm或者nack
交换机发送确认失败回调
  1. 配置spring.rabbitmq.publisher-confirms = true
  2. 实现ConfirmCallBack接口的confirm方法
  3. rabbitTemplate.setConfirmCallback(new ConfirmCallBackHandler());
队列路由确认失败回调
  1. 配置spring.rabbitmq.publisher-returns = true
  2. 实现ReturnCallback接口returnedMessage方法
  3. rabbitTemplate.setReturnCallback(new ReturnCallBackHandler());

消费者端(消息接收确认):
使用手动确认配置spring.rabbitmq.listener.simple.acknowledge-mode = manual;AUTO为自动确认;NONE为不确认
channel.basicAck()手动确认消息消费方法

  1. 消费者在声明队列时可以指定noAck参数,noACK=false,Rabbitmq会等待消费者发送ACK信号才会将消息移除.为true时,当消息被投递出去则会立即删除
  2. 当noACK=false时,队列消息分为已经投递未确认消息和未投递消息,如消息一直未确认则该消息会重新进入消息队列并设置未未投递消息
  3. RabbitMQ不会为未ack的消息设置超时时间,它判断此消息是否需要重新投递给消费者的唯一依据是消费该消息的消费者连接是否已经断开
basicRecover:未成功投递到队列的消息服务端可以使用该方法进行消息重新投递
basicReject:消费端告知broker拒绝接收该条消息,可以设置该条消息是重新入队还是丢弃,该方法一次只能拒绝一条消息
basicNack:该方法可以一次拒绝多条消息,消费端可以设置basicNack方法的multiple参数为true,服务器会拒绝指定了delivery_tag的所有未确认的消息(tag是一个64位的long值,最大值是9223372036854775807)

消息持久化

RabbitMQ 支持消息的持久化,即将消息数据持久化到磁盘上,如果消息服务器中途断开,下次开启会将持久化的消息重新发送,消息队列持久化需要保证exchange(指定durable=1)、queue(指定durable=1)和消息(delivery_mode=2)3个部分都是持久化,队列和交换机一旦创建不能修改其持久化标志,除非删除重新创建.exchange和queue两者之间有一个持久化,一个非持久化,就不允许建立绑定.

消息队列持久化包括3个部分:

1、exchange持久化,在声明时指定durable => true
2、queue持久化,在声明时指定durable => true
3、消息持久化,在投递时指定delivery_mode=> 2(1是非持久化)

集群模式

集群解决问题 : 可靠性、吞吐量、消息积压能力
RabbitMQ天然支持Clustering,共享用户、虚拟主机、队列、exchange、绑定和运行时参数。

Rabbitmq集群节点包括内存节点(RAM模式)和磁盘节点(Disk模式).内存节点性能优势展现在信息管理上例如队列、交换机、虚拟机等的增删改,在对消息的接收和发送速度和磁盘节点性能一致.一个集群至少需要一个磁盘节点.如果消息设置了持久化,则不管该节点是什么类型都存放于磁盘中.

默认集群(适合非持久化消息场景)

特点:

  1. 队列只存在于一个节点中,其他节点只存放该队列的元数据信息和该队列节点指针,消息只存放于该节点的队列中
  2. 客户端连接节点是队列消息内容所在节点则可以进行直接消息的收发.如果连接节点不是队列消息内容所在节点,则该节点会作为路由节点将消息转发至存储节点,或从存储节点拉取消息发送至客户端
  3. 交换机Exchange的元数据信息和队列绑定路由信息在所有节点上一致
  4. VirtualHost元数据信息在所有节点上一致(队列、交换器和绑定提供命名空间和安全属性)
  5. 如果队列是非持久的,当节点宕机,客户端可以重新连接到集群里的其他节点,并重新创建队列

缺陷:

  1. 不能保证高可用和容灾性,存放消息的节点故障则不能进行正常的消息消费
  2. 如果队列做了持久化,节点发生宕机则需要等该节点恢复才可以正常消费,该节点恢复前其它节点不能创建已经创建过的持久队列,如果没有做持久化则该队列上消息丢失.
镜像集群(HA方案)

由一个主节点和一/多个镜像节点组成
特点:

  1. 需要水平拓展的队列配置为镜像队列,复制于多个节点中,消息会在节点队列中同步,保证高可用.
  2. 一个队列想做成镜像队列,需要先设置Policy,集群进行队列创建时根据策略设置该队列是普通集群队列还是镜像队列
  3. 在大多数情况下,不需要在每个节点上都有副本.对于3个节点的集群,复制到2个节点,对于5个节点的集群,复制到3个节点,实现部分队列消息的共享
  4. 对队列上的所有操作都是先应用到主节点上,再传播到镜像节点上.包括排队发布消息,传递消息给消费者,跟踪消费者的确认等
  5. 消息发送到主节点队列后将复制至所有镜像队列,镜像会丢弃主服务器已经确认消费的消息
  6. 镜像队列只负责读操作,其他操作只有主节点可以进行.包括消费确认和删除.
  7. Master节点发生故障,则最老的镜像将在同步后提升为新的主服务器,将所有已发送给客户端且等待确认的所有消息重新入队

缺陷:

  1. 对集群系统存储资源消耗较大,再加上消息的同步,影响系统存储和IO性能以及带宽
  2. 不能通过扩充节点来改善提高消息积压能力

分布式部署方式(广域网集群配置部署)

RabbitMQ集群对延迟非常敏感,应该只在本地局域网中使用

Shovel(远程模式)

双活模式,已经过时.使集群可以通过广域网远程通信复制.

Federation

实现异地数据复制的主流模式,一般采用双活或者多活模型

  1. 依赖Rabbitmq的federation插件,来进行不同区域的Rabbitmq集群数据远程传输复制共享.该插件是不同的Broker间传输消息的高性能插件,连接的不同Broker双方可以使用不同的user和VH以及不同版本的MQ
  2. 该部署方式实现双/多中心模式,保证正常消息功能也提供不同中心的部分队列消息共享,以避免集群宕机造成的系统不可用情况

参考:
RabbitMQ集群架构模式
RabbitMQ的集群模式
RabbitMQ两种集群模式配置管理
消息中间件—RabbitMQ
RabbitMQ之消息确认机制
RabbitMQ(四)消息Ack确认机制

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值