【问题标题】:java spring rabbit - gracefully reject a messagejava spring rabbit - 优雅地拒绝消息
【发布时间】:2017-01-04 18:57:08
【问题描述】:

我有以下监听方法:

@Override
public void onMessage(Message message, Channel channel) {
  try {
    // do something bad :)
  } catch (Exception e){
    try {
      long dt = null != message.getMessageProperties() 
          ? message.getMessageProperties().getDeliveryTag() 
          : 0;
      channel.basicReject(dt, true);
    } catch(IOException io) {
      logger.error("IO-COMMON", io);
    }
  }
}

问题是基本拒绝不起作用,我不知道为什么。如何优雅地拒绝它?我认为如果我拒绝一条消息,它应该被重新排队并驻留就像缓存一样,然后再转到下一个工作人员。但实际上这条消息似乎丢失了。

【问题讨论】:

  • 1.空间。大约。运营商。这是每个人都同意的事情。 2. 为什么你的三元间隔这么大?我通常看到的样式,当它不在一行时,是condition\n? if-true\n: if-false;
  • 抱歉,如果您愿意,我可以修复它,我只是想强调一下送货标语。谢谢
  • 我上面提到的样式仍然单独在一行 - 注意\ns 代表新行 - 如果你想强调它,你可以发表评论解释什么是重要的是它旁边。运算符周围的空格只是为了便于阅读,但在调试时会产生很大的不同,所以这是一个好习惯。
  • 好的,我会解决的,谢谢
  • "reside is sth like cache" ?

标签: java spring-amqp spring-rabbit


【解决方案1】:

如果您自己进行确认,则需要将确认模式设置为手动。我不确定为什么它不适合你;调试/跟踪日志记录可能会有所帮助。

您应该考虑让容器处理 acks - 使用 acknowledgemode=AUTO;如果侦听器正常返回,容器通常会为任何抛出的异常重新排队消息或确认它。

您可以将defaultRequeueRejected 设置为 false(默认为 true),消息将被丢弃(或路由到 DLX/DLQ)。

您还可以抛出 AmqpRejectAndDontRequeueException 来覆盖重新排队失败消息的默认机制。

如果确认模式为 NONE - 没有确认,并且 RabbitMQ 会在消息发送后立即自动确认。

【讨论】:

  • 谢谢你,Gary,对不起,可能我把事情搞混了,但我需要我的消息留在队列中,以防出现异常。他们不应该消失,而只是排队等待消费者被修复。我认为拒绝应该可以解决问题。这就像在说“对不起,我太忙了,你留在那里等我”。如果我错了,请纠正我。我最不希望它丢失消息
  • 如果您将 ackmod 设置为 auto 并将异常抛出到容器(来自您的侦听器),则默认情况下消息将重新排队(并不断重新传递)。容器为您执行basicReject(tag, true)。
  • 是的,我在我的应用程序中看到了它,但是如果我将代码包装在 try catch 中并手动拒绝,消息似乎会丢失。谢谢
猜你喜欢
  • 2017-02-12
  • 2017-06-02
  • 2019-08-25
  • 2018-03-02
  • 2016-03-09
  • 1970-01-01
  • 2020-06-24
  • 2019-09-23
  • 2013-10-16
相关资源
最近更新 更多