返回

重构RabbitMQ队列之闲谈:RabbitMQ任务队列排错记

后端

重构RabbitMQ队列之闲谈:RabbitMQ任务队列排错记

背景

由于长期以来,在我们的Node.js服务端项目中,离线任务大部分用的是kue,这是个轻量级的任务队列。我正准备将之前的kue队列重构成RabbitMQ的队列的相关代码上线。RabbitMQ是一个功能全面的企业级消息中间件,我们用来替代现有的基于 Kue 的队列,主要是考虑到 RabbitMQ 可以更加满足我们业务的发展需求,其具有高可靠性、高吞吐量、多语言客户端等特点,能够很好地满足我们的需求。

踩过的坑

1. 使用非持久化的队列,导致任务丢失

RabbitMQ 默认情况下使用非持久化的队列,这意味着如果 RabbitMQ 服务器发生故障,队列中的所有任务都会丢失。为了避免这种情况,我们需要将队列配置为持久化,这样即使 RabbitMQ 服务器发生故障,队列中的任务也不会丢失。

2. 未设置消息的TTL,导致队列堆积

如果我们不为消息设置 TTL(生存时间),那么这些消息将永远不会从队列中删除。这可能会导致队列堆积,最终导致 RabbitMQ 服务器崩溃。为了避免这种情况,我们需要为消息设置 TTL,这样当消息过期时,它们将自动从队列中删除。

3. 未正确处理死信队列,导致任务无限重试

死信队列用于存储那些无法被消费者处理的消息。如果我们不正确处理死信队列,那么这些消息可能会无限重试,从而导致 RabbitMQ 服务器崩溃。为了避免这种情况,我们需要正确处理死信队列,例如,我们可以将死信队列中的消息记录到日志文件中,或者将其发送到另一个队列进行处理。

4. 未设置预取计数,导致消费者处理消息过慢

预取计数控制着消费者一次可以从队列中获取多少条消息。如果预取计数设置得太高,那么消费者可能会处理消息过慢,从而导致队列堆积。为了避免这种情况,我们需要根据消费者的处理能力来设置预取计数。

5. 未设置优先级,导致重要任务无法优先处理

RabbitMQ 允许我们为消息设置优先级,这样重要任务可以优先处理。如果我们不设置优先级,那么所有任务都会被平等对待,这可能会导致重要任务无法优先处理。为了避免这种情况,我们需要为重要任务设置更高的优先级。

6. 未限制并发消费者数量,导致RabbitMQ服务器崩溃

如果我们不限制并发消费者数量,那么可能会导致 RabbitMQ 服务器崩溃。为了避免这种情况,我们需要限制并发消费者数量,这样可以防止 RabbitMQ 服务器不堪重负。

写在最后

通过踩过这些坑,我对 RabbitMQ 任务队列有了更深入的了解,也对如何使用 RabbitMQ 任务队列有了更清晰的认识。希望这篇文章能对其他使用 RabbitMQ 任务队列的开发者有所帮助。

附录

RabbitMQ术语解释

生产者: 将消息发送到队列的应用程序或组件。

消费者: 从队列中接收消息并处理它们的应用程序或组件。

交换机: 将消息路由到队列的组件。

路由键: 用于将消息路由到特定队列的键。

队列: 存储消息的缓冲区。

持久化: 将队列中的消息持久化到磁盘,即使 RabbitMQ 服务器发生故障,也不会丢失。

重试: 当消费者无法处理消息时,将消息重新放入队列。

死信队列: 存储那些无法被消费者处理的消息的队列。

预取: 控制着消费者一次可以从队列中获取多少条消息。

优先级: 允许我们为消息设置优先级,这样重要任务可以优先处理。

并发: 允许我们限制并发消费者数量,这样可以防止 RabbitMQ服务器不堪重负。