RabbitMQ基本.get和确认

t5fffqht  于 2023-10-20  发布在  RabbitMQ
关注(0)|答案(3)|浏览(206)

我请求:

GetResponse response = channel.basicGet("some.queue", false); // no auto-ack
....
channel.basicAck(deliveryTag, ...);

但是,当我调用basicGet时,队列中的消息保持在“Ready”状态,而不是“Unacknowledged”状态。我希望它们处于未确认状态,这样我就可以basic.ack它们(从而将它们从队列中丢弃),或者basic.nack它们

xt0899hw

xt0899hw1#

我正在做以下操作来模拟延迟确认

消费时

1.从初始队列中获取(使用)消息。

  • 创建“PendingAck_123456”队列。

123456是消息的唯一ID。
设置以下属性

  • x-message-ttl(超时后重新排队)
  • x-expires(确保临时队列将被删除)
  • x-dead-letter-exchangex-deal-letter-routing-key 用于在TTL到期时重新排队到初始队列
  • 将消息Pending ack发布到此“PendingAck_123456”队列
  • 确认消息以将其从初始队列中删除

确认时

1.从消息ID计算队列名称并从“PendingAck_123456”队列获取
1.确认它(不需要调用.getBody())。
这将从这个挂起队列中删除它,阻止TTL重新排队它

备注

  • 一个队列,仅用于1条消息。这是一个问题,如果有 * 很多 * 这样的垃圾?
  • 重新排队的消息将在队列输入端发送。而不是在队列输出处(如真实的ACK那样)。对消息顺序有影响。
  • 应用程序将消息复制到挂起队列。这是一个额外的步骤,可能会影响整体性能。
  • 要模拟Nack/Ack,您可能需要将消息复制到初始队列,并从PendingAck队列中对其进行Ack。默认情况下,TTL将(稍后)执行此操作。
wgmfuz8q

wgmfuz8q2#

当在get之后立即执行ack时,它工作得很好。然而,在我的情况下,他们被要求分开。spring的模板在每次执行时关闭通道和连接。所以有三个选择:

  • 在应用程序的整个生命周期中保持一个通道和连接打开
  • 有某种对话范围(或最坏情况:使用会话)来存储相同的信道并重用它。
  • 每个请求使用一个信道,立即确认接收,并将消息存储在存储器中。

在前两种情况下,您无法使用spring的RabbitTemplate

5gfr0r5j

5gfr0r5j3#

GetResponse resp = channel.basicGet(queueName, false);
Envelope envelope = resp.getEnvelope();
long deliveryTag = envelope.getDeliveryTag();
channel.basicAck(deveryTag,false)

相关问题