How to resend messages repeatedly after to others consumer reject message or not answer after some time? Excluding current consumer?
How to resend messages repeatedly after to others consumer reject message or not answer after some time? Excluding current consumer?
With RabbitMQ you can use Acknowledgements. Once a message is successfully processed your consumer would ACK (acknowledge) the message and the message would then be removed from the queue. If an error is triggered while processing the message you can have your consumer NACK (negative acknowledgment) the message.
You can configure your Rabbit broker to have a Dead Letter Queue (DLQ). Once a message is marked as NACK then the message would be moved to the DLQ. Furthermore, you can set the TTL (time to live) for messages in a specific queue. If a message has been in the queue for the length of the TTL then the message would be moved to the DLQ.
With Sprint Boot AMQP (java), for example you should do the following
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Component;
@Component
public class RabbitConfirmCallback implements RabbitTemplate.ConfirmCallback {
private static final Logger logger = LoggerFactory.getLogger(RabbitConfirmCallback.class);
@Override
public void confirm(CorrelationData correlationData, boolean ack, String cause) {
if (ack && correlationData != null && correlationData.getId() != null) {
logger.info("CorrelationData with id " + correlationData.getId() + " acknowledged;");
// TODO Save to some Data Store information
// that your data with this correlationData.getId()
// wasn't successfulully delivered
// and you must try to send it again
} else {
if (ack) {
logger.warn("Unknown message acknowledgement received: " + correlationData);
} else {
logger.info("Broker didn't accept message: " + cause);
}
}
}
}
This callback method confirm(...) will be triggered after the message is delivered: whether successful, or not.
@Autowired
public void post(RabbitTemplate rabbitTemplate, RabbitConfirmCallback rabbitConfirmCallback){
rabbitTemplate.setConfirmCallback(rabbitConfirmCallback);
}
application.yamlspring:
rabbitmq:
publisher-confirm-type: correlated
rabbitTemplate.convertAndSend(exchange, routingKey, message, new CorrelationData(dataId));
Where dataId can be your understandable-on-callback's-side identifier
With such a method, consider having some maxRetries setting, to not to start an infinite cycle