boot - rabbitmq 重试
有些业务场景的下,需要对消息进行重试,在 spring boot , rabbitmq 的重试并不是依赖 rabbitmq实现的,而是通过 spring-retry 工程,通过对异常进行拦截 而进行重试操作
配置
spring.rabbitmq.addresses=192.xx.xx
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
spring.rabbitmq.listener.simple.retry.enabled=true
spring.rabbitmq.listener.simple.retry.max-attempts=3
例子
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange(value = "ex.retry.manual"),
value = @Queue(value = "q.retry.manual", durable = "true"),
key = "manual"), ackMode = "MANUAL")
public void manualRetry(String message, @Header(AmqpHeaders.DELIVERY_TAG) long deliveryTag, Channel channel) throws IOException {
int i = counter.incrementAndGet();
System.out.println(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()) + ": " + message + " counter: " + i);
doErrorManual(2, deliveryTag, channel);
}
private void doErrorManual(int type, long deliveryTag, Channel channel) throws IOException {
if (type == 1) {
//不会会重试,但消息会在rabbitmq中,服务重启后,会继续消费(unack)
try {
if (1 == 1) {
throw new NullPointerException("异常啦");
}
} catch (NullPointerException e) {
log.error("catch error: ", e);
}
} else if (type == 2) {
//会重试3后,但消息会在rabbitmq中,服务重启后,会继续消费(unack)
try {
if (1 == 1) {
throw new NullPointerException("异常啦");
}
} catch (NullPointerException e) {
log.error("catch error: ", e);
throw e;
}
} else {
//会重试3后,但消息会在rabbitmq中,服务重启后,会继续消费(unack)
if (1 == 1) {
throw new NullPointerException("异常啦");
}
}
}
@RabbitListener(bindings = @QueueBinding(
exchange = @Exchange(value = "ex.retry.auto"),
value = @Queue(value = "q.retry.auto", durable = "true"),
key = "auto"))
public void autoRetry(String message) throws IOException {
int i = counter.incrementAndGet();
System.out.println(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss").format(LocalDateTime.now()) + ": " + message + " counter: " + i);
doError(2);
}
private void doError(int type) {
if (type == 1) {
//即使开启了重试,也不会重试
try {
if (1 == 1) {
throw new NullPointerException("异常啦");
}
} catch (NullPointerException e) {
log.error("catch error: ", e);
}
} else if (type == 2) {
//会重试3后,消息被消费
try {
if (1 == 1) {
throw new NullPointerException("异常啦");
}
} catch (NullPointerException e) {
log.error("catch error: ", e);
throw e;
}
} else {
//会重试3后,消息被消费
if (1 == 1) {
throw new NullPointerException("异常啦");
}
}
}
注意
消息重试后,即使配置了不会进行到死信队列