RabbitMQ basic.get和确认

时间:2011-10-21 13:13:22

标签: java rabbitmq amqp spring-rabbit spring-amqp

我在调用:

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

但是,当我调用basicGet时,队列中的消息将保持“Ready”状态,而不是“Unacknowledged”。我希望他们不被承认,以便我可以basic.ack他们(从而将他们从队列中丢弃),或basic.nack他们

2 个答案:

答案 0 :(得分:4)

我正在执行以下操作来模仿延迟确认

消费时间

  1. 从初始队列中获取(使用)消息。
  2. 创建“PendingAck_123456”队列 123456是邮件的唯一ID 设置以下属性
    • x-message-ttl (以后重新排队 超时)
    • x-expires (以确保删除临时队列)
    • x-dead-letter-exchange x-deal-letter-routing-key 重新排队到 TTL到期时的初始队列
  3. 将消息Pending ack发布到此“PendingAck_123456”队列
  4. 确认将消息从初始队列中删除
  5. 在确认时间

    1. 从消息ID计算队列名称并从“PendingAck_123456”队列中获取
    2. 确认(无需致电.getBody()) 这将从此待处理队列中删除它,阻止TTL重新排队
    3. 说明

      • 只有1条消息的队列..如果有很多这样的队列,这是一个问题吗?
      • 将在队列输入端发送一条重新排队的消息..而不是在队列输出端(就像真正的确认一样)..对消息顺序有影响。
      • 应用程序将消息复制到Pending Queue ..这是可能对整体性能产生影响的附加步骤。
      • 要模仿Nack / Reject,您可能希望将消息复制到初始队列,并从PendingAck队列中确认它。默认情况下,TTL会执行此操作(稍后)。

答案 1 :(得分:2)

ack之后立即执行get工作正常。但是,在我的情况下,他们被请求分开了。 spring的模板在每次执行时关闭通道和连接。所以有三种选择:

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

在前两种情况下,你不能用spring RabbitTemplate

来做