Rabbitmq SpringAMQP延迟

Rabbitmq SpringAMQP延迟,rabbitmq,spring-amqp,spring-rabbit,rabbitmq-exchange,Rabbitmq,Spring Amqp,Spring Rabbit,Rabbitmq Exchange,我很难确定在SpringAMQP中延迟消息级别的方法。 如果服务不可用或抛出一些异常,我调用Webservice,我将所有请求存储到RabbitMQ队列中,并不断重试服务调用,直到它成功执行。如果服务不断抛出错误或其不可用,rabbitMQ侦听器将继续循环。(这意味着侦听器将检索消息,并在出现任何错误时进行服务调用,从而将消息重新排队) 我使用MessagePostProcessor将循环限制到X小时,但我希望在消息级别和每次尝试访问服务时启用延迟。例如,第一次尝试3000毫秒延迟,第二次尝试6

我很难确定在SpringAMQP中延迟消息级别的方法。 如果服务不可用或抛出一些异常,我调用Webservice,我将所有请求存储到RabbitMQ队列中,并不断重试服务调用,直到它成功执行。如果服务不断抛出错误或其不可用,rabbitMQ侦听器将继续循环。(这意味着侦听器将检索消息,并在出现任何错误时进行服务调用,从而将消息重新排队)

我使用MessagePostProcessor将循环限制到X小时,但我希望在消息级别和每次尝试访问服务时启用延迟。例如,第一次尝试3000毫秒延迟,第二次尝试6000毫秒,依此类推,直到我尝试x次

如果你能举几个例子就好了


你能给我一些建议吗?

嗯,你这样做是不可能的

消息重新排队与事务回滚完全相似,在事务回滚中,系统返回到异常之前的状态。因此,您绝对不能修改消息以返回队列

可能出于同样的原因,您必须查看项目,只轮询队列中的消息一次,并在内存中重试,直到成功应答或重试策略耗尽。最后,您可以从队列中删除消息或将其移动到DLQ中

请参阅。

我添加的CustomeMessage延迟交换中的更多信息
@豆子
CustomExchange延迟交换(){
Map args=new HashMap();
参数put(“x延迟类型”、“直接”);
返回新的CustomExchange(“延迟交换”、“x-delayed-message”、true、false、args);
}
添加消息后处理器
if(message.getMessageProperties().getHeaders().get(“x-delay”)==null){
message.getMessageProperties().setHeader(“x-delay”,10000);
}否则{
整型整型=(整型)message.getMessageProperties().getHeaders().get(“x-delay”);
if(整数<60000){
整数=整数+10000;
message.getMessageProperties().setHeader(“x-delay”,整数);
}
}
第一次延迟30秒,每次增加10秒,直到达到600秒。这应该是可配置的。
最后将信息发送给
convertAndSend(“延迟交换”,队列名称,消息,rabbitMQMessagePostProcessor);

Hi Artem,感谢您的回复。我使用MessagePostProcessor和CustomExchange实现了这一点@Bean CustomExchange delayExchange(){Map args=new HashMap();args.put(“x-delayed-type”,“direct”);返回新的CustomExchange(“cos delayed-exchange”,“x-delayed-message”,true,false,args);}确定。如果你觉得它很好,你可以在这里分享,作为你自己问题的答案。只需在注释中点击我就可以注意oneif(message.getMessageProperties().getHeaders().get(“x-delay”)==null){message.getMessageProperties().setHeader(“x-delay”,10000);}否则{Integer Integer=(Integer)message.getMessageProperties().getHeaders().get(“x-delay”);if(整数<60000){integer=integer+10000;message.getMessageProperties().setHeader(“x-delay”,integer);}好的。看起来很有趣,但我发现整个过程都是为了重试而进行的,这是一种开销……是的,但这样我们就不会丢失任何消息,重试会持续到x分钟,然后将消息移动到另一个队列。我们也不会因为没有在代理上确认消息而丢失它们。是的,我们可以使用Spring retry将其发送到不同的队列。请参阅我在回答中指出的文档。无论如何,您都可以接受您的回答。以防关闭线程并让人们知道有解决方案。还有一些选择
I added CustomeMessage delay exchange

    @Bean
    CustomExchange delayExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        return new CustomExchange("delayed-exchange", "x-delayed-message", true, false, args);
    }

Added MessagePostProcessor

  if (message.getMessageProperties().getHeaders().get("x-delay") == null) {
            message.getMessageProperties().setHeader("x-delay", 10000);
        } else {

            Integer integer = (Integer) message.getMessageProperties().getHeaders().get("x-delay");
            if (integer < 60000) {
                integer = integer + 10000;
                message.getMessageProperties().setHeader("x-delay", integer);
            }
        }

First time it delays 30 seconds and adds 10seconds each time till it reaches 600 seconds.This should be configurable.

And finally send the message to 

    rabbitTemplate.convertAndSend("delayed-exchange", queueName,message, rabbitMQMessagePostProcessor);