Java 独立于MessageBroker的死信队列处理方法

Java 独立于MessageBroker的死信队列处理方法,java,spring,spring-cloud-stream,messagebroker,dead-letter,Java,Spring,Spring Cloud Stream,Messagebroker,Dead Letter,我有一个项目目前使用SpringCloudStreams和RabbitMQ。我实现了一个逻辑。见下文: @组成部分 公共类重新路由DLQ{ 私有静态最终字符串原始_QUEUE=so8400in.so8400; 私有静态最终字符串DLQ=原始队列+.DLQ; 私有静态最终字符串停车场=原始停车场+停车场; 私有静态最终字符串X_RETRIES_HEADER=X-RETRIES; 私有静态最终字符串X_ORIGINAL_EXCHANGE_HEADER=RepubishMessageRecoverer

我有一个项目目前使用SpringCloudStreams和RabbitMQ。我实现了一个逻辑。见下文:

@组成部分 公共类重新路由DLQ{ 私有静态最终字符串原始_QUEUE=so8400in.so8400; 私有静态最终字符串DLQ=原始队列+.DLQ; 私有静态最终字符串停车场=原始停车场+停车场; 私有静态最终字符串X_RETRIES_HEADER=X-RETRIES; 私有静态最终字符串X_ORIGINAL_EXCHANGE_HEADER=RepubishMessageRecoverer.X_ORIGINAL_EXCHANGE; 私有静态最终字符串X_ORIGINAL_ROUTING_KEY_HEADER=RepubishMessageRecoverer.X_ORIGINAL_ROUTING_KEY; @自动连线 私人兔样板兔样板; @RabbitListenerqueues=DLQ 公共无效重新发布消息失败消息{ 映射头=failedMessage.getMessageProperties.getHeaders; Integer retriesHeader=Integer HEADER.getX\u RETRIES\u HEADER; 如果retriesHeader==null{ retriesHeader=Integer.valueOf0; } 如果检索器<3{ headers.putX_RETRIES_HEADER,retriesHeader+1; 字符串交换=字符串头。getX\u原始交换\u头; String originalRoutingKey=String HEADER.getX_ORIGINAL_ROUTING_KEY_HEADER; this.rabbitmplate.sendexchange,原始路由密钥,failedMessage; } 否则{ this.rabbitmplate.sendPARKING\u LOT,失败消息; } } @豆子 公众停车场{ 归还新停车场; } } 它实现了预期的功能,但是,它绑定到RabbitMQ,我的公司计划在一两年内停止使用此消息代理。不知道为什么,一定是一些疯狂的业务。因此,我想实现同样的东西,但要将它与任何消息代理分离

我尝试以这种方式更改重新发布方法,但不起作用:

@StreamListenerSync.DLQ 公共无效重新发布消息失败消息{ 映射头=failedMessage.getHeaders; Integer retriesHeader=Integer HEADER.getX\u RETRIES\u HEADER; 如果retriesHeader==null{ retriesHeader=Integer.valueOf0; } 如果检索器<3{ headers.putX_RETRIES_HEADER,retriesHeader+1; 字符串交换=字符串头。getX\u原始交换\u头; String originalRoutingKey=String HEADER.getX_ORIGINAL_ROUTING_KEY_HEADER; this.rabbitmplate.sendexchange,原始路由密钥,failedMessage; } 否则{ this.rabbitmplate.sendPARKING\u LOT,失败消息; } } 它失败是因为消息类具有不可变的头-在put尝试时抛出异常,表示您不能更改其值使用org.springframework.messaging.Message类

有没有办法以独立于MessageBroker的方式实现这个死信队列处理程序?

使用

MessageBuilder.fromMessage(message)
    .setHeader("foo", "bar")
     ...
    .build();

请注意,@StreamListener中的消息是spring消息,而不是spring amqp消息,因此无法使用这种方式发送模板;您需要一个输出绑定来将消息发送到。

这仍然通过rabbitTemplate绑定到RabbitMQ;这里的消息是spring消息,您可以将其发送到输出绑定。请看我的答案。谢谢你的输入。。。快速提问-我相信这会产生一个新的信息。例如,它不会与旧的默认头信息(如时间戳)混淆吗?除了ID和时间戳之外的其他头都会被复制。如果需要保留时间戳,可以将其复制到另一个标头。如果绑定器必须对有效负载执行任何消息转换,则时间戳无论如何都会更改。