Java 如何使用reactor rabbitmq处理死信队列
在我们的应用程序中,我们从spring amqp迁移到reactor rabbitmq,以更好地处理应用程序的反应性。我们一直在读反应堆项目的报告。但是,我不太确定,一旦重试失败,如何将消息发送到死信队列 在前面的实现中,我们抛出了提供的Spring AMPQ,这会导致消息自动转到死信队列,而不使用死信队列的专用发布服务器。如何在反应堆rabbitmq中执行类似操作?我是否需要编写一个专用的发布服务器,在重试用尽后从侦听器调用它,或者有其他方法来处理它。此外,是否有DLQ和停车队列的正式项目反应堆文件 以下是两个版本的一些代码示例: AMQP版本:Java 如何使用reactor rabbitmq处理死信队列,java,spring,rabbitmq,project-reactor,reactor-rabbitmq,Java,Spring,Rabbitmq,Project Reactor,Reactor Rabbitmq,在我们的应用程序中,我们从spring amqp迁移到reactor rabbitmq,以更好地处理应用程序的反应性。我们一直在读反应堆项目的报告。但是,我不太确定,一旦重试失败,如何将消息发送到死信队列 在前面的实现中,我们抛出了提供的Spring AMPQ,这会导致消息自动转到死信队列,而不使用死信队列的专用发布服务器。如何在反应堆rabbitmq中执行类似操作?我是否需要编写一个专用的发布服务器,在重试用尽后从侦听器调用它,或者有其他方法来处理它。此外,是否有DLQ和停车队列的正式项目反应
@AllArgsConstructor
public class SampleListener {
private static final Logger logger = LoggerFactory.getLogger(SampleListener.class);
private final MessageListenerContainerFactory messageListenerContainerFactory;
private final Jackson2JsonMessageConverter converter;
@PostConstruct
public void subscribe() {
var mlc = messageListenerContainerFactory
.createMessageListenerContainer(SAMPLE_QUEUE);
MessageListener messageListener = message -> {
try {
TraceableMessage traceableMessage = (TraceableMessage) converter.fromMessage(message);
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new JavaTimeModule());
MyModel myModel = mapper.convertValue(traceableMessage.getMessage(), MyModel.class);
MDC.put(CORRELATION_ID, traceableMessage.getCorrelationId());
logger.info("Received message for id : {}", myModel.getId());
processMessage(myModel)
.subscriberContext(ctx -> {
Optional<String> correlationId = Optional.ofNullable(MDC.get(CORRELATION_ID));
return correlationId.map(id -> ctx.put(CORRELATION_ID, id))
.orElseGet(() -> ctx.put(CORRELATION_ID, UUID.randomUUID().toString()));
}).block();
MDC.clear();
} catch (Exception e) {
logger.error(e.getMessage(), e);
throw new AmqpRejectAndDontRequeueException(e.getMessage(), e);
}
};
mlc.setupMessageListener(messageListener);
mlc.start();
}
@AllArgsConstructor
public class SampleListener {
private static final Logger logger = LoggerFactory.getLogger(SampleListener.class);
private final MessageListenerContainerFactory messageListenerContainerFactory;
private final Jackson2JsonMessageConverter converter;
@PostConstruct
public void subscribe() {
receiver.consumeAutoAck(SAMPLE_QUEUE)
.subscribe(delivery -> {
TraceableMessage traceableMessage = Serializer.to(delivery.getBody(), TraceableMessage.class);
Mono.just(traceableMessage)
.map(this::extractMyModel)
.doOnNext(myModel -> logger.info("Received message for id : {}", myModel.getId()))
.flatMap(this::processMessage)
.doFinally(signalType -> MDC.clear())
.retryWhen(Retry
.fixedDelay(1, Duration.ofMillis(10000))
.onRetryExhaustedThrow() //Move to DLQ
.doAfterRetry(retrySignal -> {
if ((retrySignal.totalRetries() + 1) >= 1) {
logger.info("Exhausted retries");
//Move to DLQ
}
}))
.subscriberContext(ctx -> ctx.put(CORRELATION_ID, traceableMessage.getCorrelationId()))
.subscribe();
}
);
}
注释为//移动到DLQ
的两个地方之一是,我正在猜测消息应该到达DLQ的位置。这就是我决定我不能再处理这件事的原因。如果有其他发布者推送到DLQ或任何特定设置,可以自动处理
请告诉我。我找到了这个问题的答案。我使用的是异步侦听器和
consumerautoack
。当我切换到consumermanualack
时,我得到了一个AcknowledgebleDelivery
在那里我可以做一个nack(false)
,它应该会移动到死信队列。给我们看一些代码???@prashandtpandey为这两个队列添加了代码版本。我不确定它会有多大帮助,这就是我以前没有添加它的原因。