I would like to retry consuming a message on processing/deserialiation failure for a finite number of times. After the retries are exhausted, I would like to log a message, commit the offset and move ahead with consuming further messages. For this to happen I have configured the error handler bean as below.
I am using the ack mode as MANUAL_IMMEDIATE and the auto commit is disabled by enable.auto.commit: false
Offsets are committed manually/programmatically with a reference to an Acknowledgement object (ack.acknowledge())
EDIT
@Bean
public DefaultErrorHandler errorHandler(){
ConsumerRecordRecoverer recovery = (record, ex) ->{
log.error("Retries have been exhausted. Commiting offset "+record.offset())
}
// Default backoff
BackOff backoff = new FixedBackOff(3000, 5);
DefaultErrorHandler defaultErrorHandler = new DefaultErrorHandler(recovery, backoff);
defaultErrorHandler.setCommitRecovered(true);
defaultErrorHandler.setAckAfterHandle(true);
// BackOff to use when HttpServerException occurs
BiFunction<ConsumerRecord<?,?>,Exception, BackOff> backOffFunction = (record, ex) -> {
BackOff backOff = new FixedBackOff(FixedBackOff.DEFAULT_INTERVAL, FixedBackOff.UNLIMITED_ATTEMPTS);
if(ex instanceOf HttpServerException){
return backOff;
}
return null;
}
defaultErrorHandler.removeClassification(DeserializationException.class);
defaultErrorHandler.setBackOffFunction(backOffFunction)
return defaultErrorHandler;
}
Questions:
- In the case when retries(5) have been exhausted, the idea is to log a message and commit the offset and move forward with consuming other messages. For this to happen, I have configured the below on the error handler. Please confirm if this is enough?
defaultErrorHandler.setCommitRecovered(true);
defaultErrorHandler.setAckAfterHandle(true);
- Since the DesrializationExeption is part of the fatal list, it's not going to be retried. Therefore I configured the error handler to remove it this way for a retry to occur as configured, when a Deserialization error occurs. Please confirm if this is correct?
defaultErrorHandler.removeClassification(DeserializationException.class);
- Is there a way to configure a retry policy for a given exception ? For example, retry consuming a message infinitely on a Database non availability error. This was possible in earlier versions of Springboot/Spring-kafka, as the retry policy can be set on the Listener Container. However, I could not figure this in the latest version. Please help me with any sample if its possible.
Note: I have tried the above config and it seems to work. I would like to verify with the experts that this config does what is expected and does not cause any other effects.