msgChan, err := ch.Consume(  
   q.Name, // queue  
   "",     // consumer  
   false,  // auto-ack  
   false,  // exclusive  
   false,  // no-local  
   false,  // no-wait  
   nil,    // args  
)

auto-ack结果为true时,需要进行手动确认(ack)或者重试(nack)

func (d Delivery) Ack(multiple bool)

当将 multiple 参数设置为 true 时,表示要确认当前消费者标签(consumer tag)下所有未被确认的消息,即向 RabbitMQ 确认该消费者标签接收到但尚未被确认的所有消息。如果将 multiple 参数设置为 false,则只确认当前消息一条。

因此,multiple 参数是针对某个消费者标签的,而非全局的。如果有多个消费者标签同时存在,那么分别调用它们的 Ack 方法时需要指定相应的消费者标签和 multiple 参数。

需要注意的是,使用 multiple 参数确认多条消息时,要确保这些消息都已经被正确处理。在手动确认模式下,如果存在尚未被确认的消息,RabbitMQ 就会将其重新投递到队列中,由其他消费者重新处理。如果应用程序错误地将尚未被正确处理的消息标记为“已确认”,可能会导致消息丢失或重复处理等问题。

func (d Delivery) Nack(multiple, requeue bool) error

channel.Nack(Negative Acknowledgement)方法用于将当前正在处理的消息标记为“未确认(Unacknowledged)”,并在需要时将其重新投递到队列上。与 channel.Ack 不同的是,channel.Nack 方法可以设置 multiplerequeue 两个参数。

  • multiple 表示是否将当前消息之前的所有未确认消息都标记为“未确认”。如果将 multiple 参数设置为 true,那么当前消息之前的所有未确认消息都会被标记为“未确认”并重新投递到队列的头部。否则,只有当前消息会被标记为“未确认”。

  • requeue 表示当消息被重新投递到队列上时,是否将其重新放回到队列的头部。如果将 requeue 参数设置为 true,那么消息会被重新放回到队列的头部,等待下一个消费者重新接收它。否则,消息会被直接丢弃。

通常情况下,我们使用 channel.Nack 方法将消息标记为“未确认”时,需要将 requeue 参数设置为 true,以便重新投递该消息。这样做可以实现消息的“失败重试(Failed Retry)”机制。当消费者无法处理某个消息时,可以调用 channel.Nack 方法将该消息重新投递到队列的头部,并在一段时间后再次接收到该消息,以尝试重新处理。如果消息经过多次重新投递后仍然无法被成功处理,就会被认为是“死信消息(Dead Letter Message)”,并被发送到死信队列中。

需要注意的是,如果使用了手动确认模式,那么在重新投递消息之前,需要先调用 channel.Ackchannel.Reject 方法来确认或拒绝当前正在处理的消息。如果不进行确认或拒绝操作,消息可能会被重新投递到其他消费者或者死信队列中。

在 RabbitMQ 中,x-message-ttl 参数可以在声明队列、发布消息和订阅消息时进行设置,具有不同的含义和用途。下面分别介绍它们的作用:

  1. 声明队列时设置 x-message-ttl

在声明队列时,可以通过 arguments 参数设置 x-message-ttl,以指定该队列中消息的存活时间。这意味着,如果一个消息在该队列中等待超过指定的时间,RabbitMQ 将自动将其删除。这对于在队列中积累大量未处理消息的场景非常有用,可以避免队列因消息堆积而被过度填满,进而影响整个系统的稳定性。

  1. 发布消息时设置 expiration

当您通过 AMQP 协议发布一条消息时,可以设置 expiration 字段,以指定该消息的存活时间。与队列的 x-message-ttl 类似,如果一条消息在队列中等待的时间超过指定的时间,RabbitMQ 将自动将其删除。这也可以防止未处理的消息在队列中积累过多,从而导致系统性能下降。

  1. 订阅消息时设置 x-message-ttl

在订阅消息时,可以通过 arguments 参数设置 x-message-ttl,以指定在消费者从队列中接收到消息后,如果该消息在消费者队列中等待超过指定的时间,则自动将其删除。这对于需要立即处理消息的场景非常有用,可以确保消息不会在队列中长时间等待而不被及时处理。

需要注意的是,当同时设置了队列的 x-message-ttl 和消息的 expiration 参数时,消息的 expiration 参数会优先于队列的 x-message-ttl 参数。也就是说,如果消息的 expiration 时间比队列的 x-message-ttl 时间更短,那么消息将在消息的 expiration 时间到达之前被删除。如果消息的 expiration 时间比队列的 x-message-ttl 时间更长,那么消息将在队列的 x-message-ttl 时间到达之前被删除。