简体   繁体   English

静默地将作业返回队列

[英]Return a job to the queue silently

I have a RabbitMQ with a job queue defined, and I'm consuming it with the Java through Spring Framework. 我有一个定义了工作队列的RabbitMQ,并且正在通过Spring Framework与Java一起使用它。 I know that, if I throw an exception somewhere in the code while processing the job which I received from the queue, will return the job to the queue. 我知道,如果在处理从队列接收到的作业时在代码中的某个地方抛出异常,会将作业返回到队列。 But, is there some other way to return a job to the queue, without throwing and exception, or returning a job "manually" to the queue? 但是,还有其他方法可以将作业返回队列,而不会引发异常,也可以“手动”将作业返回队列吗?

The solution may depend on abstraction that you use: 该解决方案可能取决于您使用的抽象:


Spring Cloud Streams 春季云流

I would do this using a Spring Cloud Stream Processor that processes messages and sets the routingKeyExpression . 我将使用Spring Cloud Stream Processor来执行此操作,该处理器处理消息并设置routingKeyExpression

The bindings: 绑定:

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

Spring AMQP 春季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 Client RabbitMQ Java客户端

You can go to the lower layer too and use negative acknowledgement and re-queue : 您也可以转到下层并使用否定确认并重新排队

This example rejects two messages with a single call to the broker (the second argument on basicNack is the multiple flag): 此示例通过一次调用代理来拒绝两条消息( basicNack的第二个参数是Multiple标志):

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

When a message is requeued, it will be placed to its original position in its queue, if possible. 消息重新排队后,将尽可能放置在其队列中的原始位置。 If not (due to concurrent deliveries and acknowledgements from other consumers when multiple consumers share a queue), the message will be requeued to a position closer to queue head. 否则(由于多个消费者共享一个队列时,由于其他消费者的并发传递和确认),该消息将重新排队到更靠近队列头的位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM