如何在一段时间后再次重发消息给其他消费者拒绝消息或不回答?排除当前的消费者?
答案 0 :(得分:1)
通过RabbitMQ,您可以使用Acknowledgements。一旦成功处理了一条消息,您的使用者将对消息进行ACK(确认),然后将该消息从队列中删除。如果在处理消息时触发了错误,则可以让使用者对消息进行NACK(否定确认)。
您可以将Rabbit代理配置为具有Dead Letter Queue(DLQ)。一旦消息被标记为NACK,则该消息将被移至DLQ。此外,您可以为特定队列中的邮件设置TTL(生存时间)。如果一条消息已经在TTL长度的队列中,那么该消息将被移到DLQ。
答案 1 :(得分:1)
例如,对于Sprint Boot AMQP(java),您应该执行以下操作
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);
}
}
}
}
此回调方法confirm(...)
将在传递消息后触发:是否成功。
@Autowired
public void post(RabbitTemplate rabbitTemplate, RabbitConfirmCallback rabbitConfirmCallback){
rabbitTemplate.setConfirmCallback(rabbitConfirmCallback);
}
application.yaml
spring:
rabbitmq:
publisher-confirm-type: correlated
rabbitTemplate.convertAndSend(exchange, routingKey, message, new CorrelationData(dataId));
dataId
是您可以理解的回叫方标识符
使用这种方法,请考虑进行一些maxRetries
设置,以免开始无限循环