RabbitMQ学习

RabbitMQ学习

1. RabbitMQ高级特性

  1. 消息可靠性
    1. 发送消息但消息却未被消费,就会出现消息不可靠
    2. 消息可靠性原则就是消息至少被消费一次
    3. 并不是所有的业务都对可靠性有要求
  2. 发送者的可靠性
    1. 发送者重连是否连接到MQ,阻塞
      1. 当发送者发送消息时连接不上MQ就会导致消息发送失败,故可以通过配置开启失败重连![[Pasted image 20241111123411.png]]
      2. 但spring-amqp提供的重试机制是阻塞时的,即发送消息时如果连接失败则会以阻塞的形式重连连接上后发送消息然后异步处理消息连接不上会一直阻塞等待重连,阻塞式重连,对于高性能要求建议关闭重试机制,或者设置合理的重试等待时长和次数
      3. 该配置仅仅是连接MQ的重试不是消息发送失败后的重试,仅仅是连接MQ的重试,发送者对于MQ的重连,是阻塞式的,连接不上会一直重连
    2. 发送者确认是否投递成功
      1. 关心的是消息发送是否成功
      2. ConfirmRetuen 两种确认机制,开启确认机制后,当MQ成功收到消息后会返回确认消息给发送者
      3. 消息成功发送到MQ,且对于非持久化队列入队成功或者持久化队列持久化成功时,就会返回ACK表示投递成功
      4. 如果路由失败则会额外return路由异常原因return只在路由失败时返回路由异常信息路由失败也会返回ACK表示消息发送到了MQ,但因为找不到指定的路由,故会return额外的路由异常信息
      5. 否则返回NACK表示投递失败
    3. 发送者确认代码实现
      1. 发送者发送消息后要对消息发送发送成功进行确认,有两种方式:同步等待(会一直等待MQ返回确认)、异步确认(由MQ发起回调函数,要在发送者方配置回调函数,return函数只配置一次,在rabbitTemplate中配置,而回调函数每发送一次都要配置一次)
      2. SpringAMQP实现发送者确认,要添加配置文件,选择确认模式,有同步等待、异步确认和关闭确认![[Pasted image 20241111124831.png]]
      3. simple同步等待方式发送者发送消息会一直阻塞等待MQ返回ACK或者NACK后才会继续
      4. correlated异步回调方式发送者发送消息后无需等待继续执行,由MQ回调返回确认消息
      5. 开启回调机制后要编写回调函数,且每个RabbitTemplate只可以配置一个回调函数ReturnCallback(),要在项目启动过程中对其进行配置![[Pasted image 20241111125801.png]]
      6. ConfirmCallback()回调函数在每次发送消息时就要配置当前消息发送的回调函数,要在发送消息时传入一个CorrelationData对象,其中有一个uuid唯一标识发送的消息且配置消息的Confirm回调函数,使用getFure()然后addCallback()来添加回调函数,此时Failure表示消息回调失败(指回调消息没有接收到,不是NACK,NACK也是消息回调成功,只不过回调的是NACK)Success表示消息回调成功,且回调成功有ACK和NACK两种情况 ![[Pasted image 20241111130308.png]]
      7. ReturnCallback()是Return的回调函数,每一个RabbitTemplate只需要配置一次,只有路由异常时才会return,而 ConfirmCallback()是消息发送的回调函数,此时每次发送消息都要配置当前消息发送的回调函数,在发送消息时传入当前消息的回调函数,要配置回调失败和成功的情况,成功中包括ACK和NACK
    4. 尽量不要使用发送者确认,会有额外的网络开销![[Pasted image 20241111131850.png]]
  3. MQ的可靠性
    1. 默认情况下,MQ将接收到的消息只保存在内存中降低消息收发的延迟(不用读磁盘),此时MQ宕机会导致消息丢失且内存空间有限,可能导致消息积压引发MQ阻塞(内存满了),当内存过满时,会进行配置OUT,将内存中消息放到磁盘中此时MQ会阻塞,不会接收任何新的消息
    2. 数据持久化
      1. 交换机持久化:创建的交换机会保存到磁盘中,此时MQ重启时交换机依然存在
      2. 队列持久化
      3. 消息持久化:持久化消息重启MQ后依然存在,开启持久化后消息会保存进磁盘,且内存也会有一份但当内存很满时就会直接清理内存,而不用配置OUT,此时MQ不会阻塞
      4. 使用spring创建的交换机和队列默认都是durable持久化的
    3. LazyQueue
      1. 数据持久化方式的性能不太好
      2. 消息直接存放到磁盘而不是内存内存只保留默认2048条最近使用的消息,消费者要消费消息时且不在内存中才会去磁盘中加载到内存![[Pasted image 20241111133522.png]]
      3. 默认所有的队列都是LazyQueue模式![[Pasted image 20241111133751.png]]
    4. ![[Pasted image 20241111134023.png]]
  4. 消费者的可靠性
    1. 消费者确认机制
      1. 消费者确认机制是指当消费者处理完消息后向MQ发送一个确认信息告知MQ自己的消息处理状态返回ACK时MQ删除消息NACK(处理失败)时MQ要再次投递消息REJECT表示消息处理失败并拒绝消息(消息出错了,不需要重传,否则仍会错误,故直接拒绝),此时MQ会删除消息![[Pasted image 20241111134146.png]]
      2. 因为消费者的逻辑在spring中实现,故此时不需要手动设置回调函数,可以由spring根据消费中是否返回异常来回传给MQ对应的消息,正常处理返回ACK,抛出异常返回NACK或者REJECT,取决于异常类型,只需要在配置文件中设消费者确认机制为 auto 即可,也可以设置为 manual 来自己手动配置回调函数,或者设置为 none,此时每次都会返回ACK,由MQ删除消息,不安全不建议使用![[Pasted image 20241111135153.png]]
      3. 对于auto模式,如果消费者处理出现异常则可能会返回NACK,此时MQ会重新投递直到返回ACK或者REJECT,且MQ投递消息后消息会变为UNACKED模式,如果返回NACK,则消息会恢复,如果返回ACK,则消息会被删除
      4. 当消费者抛出消息转换异常时,则此时会返回REJECT,则MQ不会重新投递,而是直接删除消息
    2. 消费失败处理
      1. 消费者可以通过消息确认和消息重试来通过可靠性![[Pasted image 20241111182815.png]]
      2. 失败重试机制,当消息处理失败时,会返回NACK给MQ,此时MQ收到后会进行消息重试重新发送消息给消费者,但如果一直失败时就会导致MQ消息处理飙升,此时可以利用spring的retry机制当消费者出现异常时利用本地重试,而不是无限制的requeue到MQ队列,即消费者处理失败后返回NACK,此时不会返回到MQ中,而是在spring中对消息进行重试,此时**可以配置重试次数每当重试均失败时则可以配置如何处理 ![[Pasted image 20241111180600.png]]
      3. 本地重试次数内均失败时,默认是直接拒绝然后删除消息此时可以通过配置MessageRecover来实现别的模式,如重新把消息放到一个失败交换机中然后投递到失败队列中(失信队列),由人工来处理 ![[Pasted image 20241111180903.png]]![[Pasted image 20241111181737.png]]![[Pasted image 20241111182411.png]]
      4. 且消息处理重试必须开启配置时才会生效,故 MessageRecover 配置类可以只在配置spring.rabbitmq.listener.simple.retry开启时才进行处理
    3. 业务幂等性
      1. 在程序开发中,指同一个业务执行一次或者多次对业务状态的影响是一致的,如查询业务,多次查询对结果无影响,但扣减余额多次执行就会影响,删除操作也是幂等操作
      2. 对于非幂等业务必须通过某种方式保证它的幂等性
      3. 添加消息唯一ID:给每个消息设置唯一消息ID利用ID区分是否是重复消息,通过在Jackson消息转换器中设置为每个消息设置ID,但此时需要在业务中进行额外操作 ![[Pasted image 20241111184002.png]]
      4. 业务判断结合业务逻辑,基于业务本身来判断幂等性,如修改状态前先查询状态是否已经修改过,也可以直接使用SQL语句进行判断
    4. 如果保证支付和交易之间订单状态一致性:支付服务和交易服务之间通过MQ队列异步通信,且通过生产者确认机制、消费者确认机制、失败重试等策略确保消息投递和处理的可靠性,同时开启MQ的持久化,避免服务宕机导致消息丢失 ![[Pasted image 20241111185250.png]]
    5. 消息处理失败的兜底方案:消息重试机制开启重试,且可以设置多次重试失败后将消息转发到错误交换机中人工介入,也可以让交易服务主动定时去查询订单支付状态,即使MQ通知失败还可以利用定时任务去兜底查询,保证数据最终一致性![[Pasted image 20241111185753.png]]
  5. 延迟消息
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值