我正在使用spring-kafka 2.2.6。我已经使用了SeekToCurrentErrorHandler和ErrorHandlingDeserializer2。 SeekToCurrentErrorHandler当前配置为在三次重试后记录消息。有什么方法可以跳过重试验证错误(由Spring中的Validator实现捕获)和消息转换错误?容器错误处理程序(即SeeToCurrentErrorHandler)会拦截所有错误。我应该重写SeeToCurrentErrorHandler的handle方法吗?
@Bean
public ConcurrentKafkaListenerContainerFactory<String, Object> kafkaListenerContainerFactory() {
ConcurrentKafkaListenerContainerFactory<String, Object> factory = new ConcurrentKafkaListenerContainerFactory<>();
factory.setConsumerFactory(consumerFactory());
factory.setConcurrency(this.kafkaConfigProperties.getConsumerConcurrency());
factory.setAutoStartup(false);
factory.setErrorHandler(new SeekToCurrentErrorHandler((c, e) -> {
LOG.info(e.getMessage());
}, this.kafkaConfigProperties.getRetryCount()));
return factory;
}
@Bean
public ConsumerFactory<String, Object> consumerFactory() {
Map<String, Object> map = new HashMap<>();
Properties consumerProperties = getConsumerProperties();
consumerProperties.forEach((key, value) -> {
map.put((String) key, value);
});
KafkaSoapMessageConverter kafkaSoapMessageConverter = new KafkaSoapMessageConverter();
Map<String, Object> configMap = new HashMap<>(1);
configMap.put(KafkaSoapMessageConverter.CLASS_TO_DESERIALIZE, MyClass.class);
kafkaSoapMessageConverter.configure(configMap, false);
ErrorHandlingDeserializer2<Object> errorHandlingDeserializer = new ErrorHandlingDeserializer2<>(
kafkaSoapMessageConverter);
DefaultKafkaConsumerFactory<String, Object> consumerFactory = new DefaultKafkaConsumerFactory<>(map);
consumerFactory.setValueDeserializer(errorHandlingDeserializer);
return consumerFactory;
}
编辑
我使用了以下代码
if(DeserializationException.class == e.getClass()
|| e.getCause().getClass() == MethodArgumentNotValidException.class) {
SeekUtils.doSeeks(records, consumer, e, true, (c, e) -> { return true; }, LOG);
} else {
super.handle(e, records, consumer, container);
}
答案 0 :(得分:0)
版本2.3(当前为2.3.5)添加了配置可重试哪些异常的功能:
/**
* Set an exception classifications to determine whether the exception should cause a retry
* (until exhaustion) or not. If not, we go straight to the recoverer. By default,
* the following exceptions will not be retried:
* <ul>
* <li>{@link DeserializationException}</li>
* <li>{@link MessageConversionException}</li>
* <li>{@link MethodArgumentResolutionException}</li>
* <li>{@link NoSuchMethodException}</li>
* <li>{@link ClassCastException}</li>
* </ul>
* All others will be retried.
* When calling this method, the defaults will not be applied.
* @param classifications the classifications.
* @param defaultValue whether or not to retry non-matching exceptions.
* @see BinaryExceptionClassifier#BinaryExceptionClassifier(Map, boolean)
*/
public void setClassifications(Map<Class<? extends Throwable>, Boolean> classifications, boolean defaultValue) {
这是设置默认值的方式:
Map<Class<? extends Throwable>, Boolean> classified = new HashMap<>();
classified.put(DeserializationException.class, false);
classified.put(MessageConversionException.class, false);
classified.put(MethodArgumentResolutionException.class, false);
classified.put(NoSuchMethodException.class, false);
classified.put(ClassCastException.class, false);
此外,您可以为默认值添加例外:
/**
* Add an exception type to the default list; if and only if an external classifier
* has not been provided. By default, the following exceptions will not be retried:
* <ul>
* <li>{@link DeserializationException}</li>
* <li>{@link MessageConversionException}</li>
* <li>{@link MethodArgumentResolutionException}</li>
* <li>{@link NoSuchMethodException}</li>
* <li>{@link ClassCastException}</li>
* </ul>
* All others will be retried.
* @param exceptionType the exception type.
* @see #removeNotRetryableException(Class)
* @see #setClassifications(Map, boolean)
*/
public void addNotRetryableException(Class<? extends Exception> exceptionType) {
Assert.isTrue(this.classifier instanceof ExtendedBinaryExceptionClassifier,
"Cannot add exception types to a supplied classifier");
((ExtendedBinaryExceptionClassifier) this.classifier).getClassified().put(exceptionType, false);
}