静默地将作业返回队列

时间:2018-11-30 21:56:02

标签: java spring rabbitmq message-queue

我有一个定义了工作队列的RabbitMQ,并且正在通过Spring Framework与Java一起使用它。我知道,如果在处理从队列接收到的作业时在代码中的某个地方抛出异常,会将作业返回到队列。但是,还有其他方法可以将作业返回队列,而不会引发异常,或者“手动”将作业返回队列吗?

1 个答案:

答案 0 :(得分:1)

解决方案可能取决于您使用的抽象:


Spring Cloud Streams

我会使用Spring Cloud Stream Processor来执行此操作,该routingKeyExpression处理消息并设置negative acknowledgement and re-queue

绑定:

=> theSourceQueue 
   => myProcessor(message) consumes messages and setts routing key as a header
      => DestinationExchange 
         => route 1 => theSourceQueue
         => route 2 => ?

春季AMQP

import com.rabbitmq.client.Channel;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Header;
import org.springframework.stereotype.Component;

import java.io.IOException;

@Component
public class Receiver {
    @RabbitListener(queues = "my-messages")
    public void receiveMessage(String payload, Channel channel, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag) throws IOException {
        System.out.println("Received message: `" + payload + "`, deliveryTag: " + deliveryTag);
        channel.basicNack(deliveryTag, false, true);
    }
}

RabbitMQ Java客户端

您也可以转到下一层并使用basicNack

  

此示例通过一次调用代理来拒绝两条消息(solution one上的第二个参数是多标记):

GetResponse gr1 = channel.basicGet("some.queue", false);
GetResponse gr2 = channel.basicGet("some.queue", false);
channel.basicNack(gr2.getEnvelope().getDeliveryTag(), true, true);
     

将消息重新排队后,如果可能的话,它将被放置到其队列中的原始位置。否则(由于多个消费者共享一个队列时,由于并发传递和来自其他消费者的确认),邮件将重新排队到更靠近队列头的位置。