目录

1.幂等性保障

2.顺序性保障

3.消息积压


1.幂等性保障

(1)介绍幂等性

幂等性,最早期是数学和计算机科学中某些运算的性质,它们可以被多次应用,而不会改变初始应用的结果

比如说,重复多次调用同一个函数,函数返回的结果也相同。

比如,牛羊吃进去的是草,拉出来的也是

(2)MQ上的幂等性

定义:对于MQ的幂等性,是指同一条消息,进行多次消费,对系统的影响的相同的

为什么会有同一个消息多次消费,是因为可能触发重试等机制

所以对于消息中间件,对消息传输保障分为三个层级:

1)At most once:最多一次。消息可能会丢失,但绝不会重复传输。

2)At least once:最少一次。消息绝不会丢失,但可能会重复传输。

3)Exactly once:恰好一次。每条消息肯定会被传输一次且传输一次。

对于目前的中间件来说,只能支持前面两种,最后一种也无法做到。

(3)MQ如何保障幂等性

为什么要保证幂等性?

比如用户下单一个商品,在支付页面因为网络缘由,多次点击,这个时候就只能认为是一次消费。

所以幂等性保障,就是可以正确的处理相同重复的消息。对于RabbitMQ保障幂等性有两个方面:保证全局ID和代码逻辑判断,主要方法还是需要靠全局唯一ID

1)全局唯一ID

做法:给每条消息分配一个全局唯一的ID。这个ID可以自定义生成,比如UUID,UUID+时间戳等。

当消费者收到消息后,就可以根据唯一ID判断该消息是否已经被消费过,如果已经被消费观过,则可以不做处理,进而可以避免重复消费的问题。

对于未消费过的消息,就可以进行消费;在消费完成后,就需要把该ID进行保存起来,表明该ID的消息已经被消费过。

2)业务逻辑判断

这个方面就考验程序猿的代码能力了。比如通过检查数据库中是否已经存在相关的数据记录;或者在处理消息前,检查相关业务的状态,确保消息对应的操作尚未执行,然后再进行处理。


2.顺序性保障

顺序性保障,是指消费者消费的消息和生产者生产的消息顺序一致。

对于很多的业务场景,对顺序性是没有要求的;但是一些场景下是有要求的,比如对同一个用户的同一个信息进行修改。

(1)会打破顺序性的场景

1)多个消费者

当存在多个消费者的时候,消息被哪一个消费者消费是不确定的,也可能并行处理,就会导致消息的顺序性无法保证

2)网络波动或异常

在消息传递过程中,如果出现网络波动或者异常,可能导致消息会重新入队,进行直接影响顺序性。

3)消息重试

消费者消费完成后没有及时对消息进行确认,或者确认丢失,MQ可能认为消息未发送成功进而重试,也会导致消息处理的顺序性问题。

4)消息路由问题

消息会根据不同的路由规则进入不同的队列,因为每个队列的情况都会不太一样,就无法保证全局的顺序性。

5)死信队列

当消息因为一些原因进入死信队列后,再被消费者消费,就无法保证消息的顺序性和生产者发送消息的顺序一致。


上述的比较常见的场景,如果需要保障顺序性,就需要做出相应的处理。

(2)如何保障顺序性

消息顺序性保障分为:局部顺序性保障和全局顺序性保障。一般都为局部性保障,全局性保障较为困难。

  1. 局部顺序性保障:指的是在单个队列内部保证消息的顺序
  2. 全局顺序性保障:指的是在多个队列或者多个消费者之间的顺序性保障

下面介绍两个常用的顺序性保障策略

1)单个消费者和单个队列

这样的策略下,就能从很大的几个方面下杜绝了一些情况,进而跟容易保障消息的顺序性问题。

2)分区消费

这里的分区指的是将一个队列划分成多个区域,每个区域引入一个消费者进行消费,这个时候保障每个分区内的顺序性即可。

3)消息确认机制

使用手动消息确认机制,消费者在处理完⼀条消息后,显式地发送确认,这样RabbitMQ才会移除并继续发送下⼀条消息.

4)业务逻辑控制

在某些情况下,即使消息乱序到达,也可以在业务逻辑层⾯实现顺序控制,比如通过在消息中嵌入序列号,并在消费时根据这些信息来处理


3.消息积压

消息积压,指的是在消息队列中,待处理的消息数量超过了消费者的处理能力,导致消息在队列中不断堆积的现象。

(1)产生的原因

  • 消息生产过快

在高流量或者高负载的情况下,生产者以极高的速率发送消息,超过了消费者的处理能力,这也就是本质原因

  • 消费者处理能力不足
  1. 消费端业务逻辑复杂,耗时长
  2. 消费端代码性能低
  3. 系统资源限制,如CPU、内存、磁盘I/O等也会限制消费者处理消息的效率
  4. 异常处理不当。比如消费者在处理消息时出现异常,导致消息无法被正确处理和确认
  • 网络问题

比如网络延迟或不稳定,消费者无法及时接收或者确认消息,最终导致消息积压

  • RabbitMQ服务器配置偏低

消息积压会导致系统性能下降,影响用户体验,甚至导致系统崩溃

(2)解决方案

  • 提高消费者效率
  1. 增加消费者实例数量,比如多引入新的机器
  2. 优化业务逻辑,比如使用多线程来处理业务
  3. 设置prefetchCount,当一个消费者阻塞时,消息转发到其他未阻塞的消费者中
  4. 消息发送异常时,设置合适的重试策略,或者转入死信队列
  • 限制生产者速率
  1. 流量控制:在消息生产者中实现流量控制逻辑,根据消费者处理能力动态调整发送速率
  2. 限流:使用限流工具,为消息发送速率设置一个上限
  3. 设置过期时间:如果消息过期未消费,可以配置死信队列,以避免消息丢失,并减少对主队列的压力
  • 资源与配置优化

比如升级RabbitMQ服务器的硬件,调整RabbitMQ的配置参数等

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部