RabbitMQ 应用问题

目录

1. 幂等性保障

1.1 幂等性

1.2 解决方案

2. 顺序性保障

2.1 顺序性

2.2 顺序性保障方案

3. 消息积压问题

3.1 原因

3.2 解决方案


1. 幂等性保障

1.1 幂等性

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

应用程序幂等性

在应用程序中,幂等性就是指对一个系统进行重复调用(相同参数),无论请求多少次,这些请求对系统的影响都是相同的结果

例如数据库中的 Select 操作,不同时间两次查询的结果可能不同,但是这个操作是符合幂等的,幂等指的是对资源的影响,而不是返回结果

MQ 幂等性

对于 MQ 而言,幂等性是指同一条消息,多次消费,对系统的影响是相同的,一般消息中间件的消息传输保障分为三个层次

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

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

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

RabbitMQ 支持"最多一次"和"最少一次",对于恰好一次,目前 RabbitMQ 还做不到,在业务中使用时,对于可靠性要求比较高的场景,建议使用"最少一次",防止消息丢失,"最多一次"会因为消息发送的过程中,因为网路问题,消费出现异常原因,导致消息丢失

但是"最少一次"就会造成消费端会收到重复的消息,也会造成同一条消息进行多次处理,对于重要的业务,如果不对重复的消息进行处理,会造成严重事故

1.2 解决方案

MQ 消费者幂等性的解决方案:

全局唯一 ID

1)为每条消息分配一个唯一的标识符,比如 UUID 或者 MQ 消息中的唯一 ID,但是一定要保证唯一性

2)消费者收到消息后,先用该 ID 判断该消息是否已经消费过了,如果消费过了,则放弃处理

3)如果未消费,消费者开始消费消息,业务处理成功后,把唯一 ID 保存到数据库或者 Redis 中

此处可以使用 Redis 的原子操作 setnx 来保证幂等性,将唯一 ID 作为 key 放到 Redis 中(setnx messag 1),返回 1,说明没有消费过,正常消费,返回 0,说明已经消费过了,抛弃

2. 顺序性保障

2.1 顺序性

消息的顺序性是指消费者消息和生产者发送消息的顺序是一致的

例如生产者发送的消息分别是 1,2,3,那么消费者也是按照 1,2,3 的顺序进行消费的,在很多业务场景下,消息的消费是不用保证顺序的,例如使用 MQ 实现订单超时的处理,但是有些业务场景可能存在多个消息顺序处理的情况,如果存在多个生产者同时发啊消息,无法确认消息到达RabbitMQ Broker 的前后顺序

下面的情况可能会打破 RabbitMQ 的顺序性

1)多个消费者:当队列配置了多个消费者时,消息可能会被不同的消费者并行处理,从而导致消息处理的顺序性无法保证

2)网路波动或异常:在消息传递的过程中,如果出现网路波动或异常,可能会导致消息确认(ACK)丢失,从而使得消息被重新入队和重新消费,造成顺序性问题

3)消息重试:如果消费者在处理消息后未能及时发送确认,或者确认消息在传输过程中丢失,那么 MQ 可能会认为消息未被成功消费而进行重试,这也可能导致消息处理的顺序性问题

4)消息路由问题:在复杂的路由场景中,消息可能会根据路由键被发送到不同的队列,从而无法保证全局的顺序性

5)死信队列:消息因为某些原因(如消费端拒绝消息)被放入死信队列,死信队列被消费时。无法保证消息的顺序和生产者发送消息的顺序⼀致

2.2 顺序性保障方案

消息顺序性保障分为:局部顺序性保证和全局顺序性保证

局部顺序性通常指的是在单个队列内部保证消息的顺序,全局顺序性是指在多个队列或多个消费者之间保证消息的顺序

1)单队列单消费者

最简单的方法就是使用单个队列,并由单个消费者进行处理,同⼀个队列中的消息是先进先出的,这是 RabbitMQ 来帮助我们保证的

2)分区消费

单个消费者的吞吐太低了,当需要多个消费者以提高处理速度时,可以使用分区消费,把一个队列分割成多个分区,每个分区由一个消费者处理,以此来保持每个分区内消息的顺序性

3)消息确认机制

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

3. 消息积压问题

3.1 原因

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

通常有以下几种原因:

1)消息生产过快:在高流量或者高负载的情况下,生产者以极高的速度发送消息,超过了消费者的处理能力

2)消费者处理能力不足:消费者处理消息的速度跟不上消息生产的速度,也会导致消息在队列中积压

3)网路问题

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

3.2 解决方案

1)提高消费者效率

a. 增加消费者实例数量,例如新增机器

b. 优化业务逻辑,采用多线程来处理业务

c. 设置 prefetchCount,当一个消费者阻塞时,消息转发到其他未阻塞的消费者

d. 消息发生异常时,转入死信队列

2)限制生产者速率

a. 在消息生产者中实现流量控制逻辑,根据消费者处理能力动态调整发送速率

b. 设置过期时间,如果消息过期未消费,可以配置死信队列,避免消息丢失,并减少对主队列的压力

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值