#spring-cloud-stream #spring-retry #spring-cloud-stream-binder-kafka
#поток spring-cloud-stream #spring-повторная попытка #spring-cloud-stream-binder-kafka
Вопрос:
У меня есть проект Spring Cloud Stream, использующий Kafka binder, и я хочу добавить функциональность повтора, я пытаюсь использовать RetryTemplate и указать определенные исключения, которые я хочу обработать, но из-за того, что любое исключение обернуто MessageTransformationException, я не могу настроить его так, как я хочу. Есть ли способ обработать вложенное исключение?
Шаблон повторной попытки
@StreamRetryTemplate
public RetryTemplate myRetryTemplate() {
RetryTemplate retryTemplate = new RetryTemplate();
ExceptionClassifierRetryPolicy exceptionClassifierRetryPolicy =
new ExceptionClassifierRetryPolicy();
Map<Class<? extends Throwable>, RetryPolicy> policyMap = new HashMap<>();
policyMap.put(MyException.class, new SimpleRetryPolicy(4));
exceptionClassifierRetryPolicy.setPolicyMap(policyMap);
retryTemplate.setRetryPolicy(exceptionClassifierRetryPolicy);
return retryTemplate;
}
Отслеживание стека
org.springframework.integration.transformer.MessageTransformationException: Failed to transform Message in bean '...' for component ‘...'; nested exception is org.springframework.messaging.MessageHandlingException: error occurred during processing message in 'MethodInvokingMessageProcessor' [org.springframework.integration.handler.MethodInvokingMessageProcessor@4dba2d07]; nested exception is MyException
Таким образом, он игнорирует конфигурацию, которую я настроил для MyException
Ответ №1:
Вам нужно установить traverseCauses
значение true
в SimpleRetryPolicy
.
/**
* Create a {@link SimpleRetryPolicy} with the specified number of retry attempts. If
* traverseCauses is true, the exception causes will be traversed until a match is
* found.
* @param maxAttempts the maximum number of attempts
* @param retryableExceptions the map of exceptions that are retryable based on the
* map value (true/false).
* @param traverseCauses is this cause traversable
*/
public SimpleRetryPolicy(int maxAttempts, Map<Class<? extends Throwable>, Boolean> retryableExceptions,
boolean traverseCauses) {
Итак:
new SimpleRetryPolicy(4, Collections.singletonMap(Exception.class, true), true);
Комментарии:
1. Спасибо, Гэри, работает ли это таким образом с Policyap? Когда я пытаюсь использовать одну SimpleRetryPolicy, она работает нормально, но не с картой политик, я изменил свой пример таким образом POLICYAP.put(MyException.class , новая SimpleRetryPolicy(4, Collections.singletonMap(MyException.class , верно), верно));
2. Я не заметил, что вы использовали
ExceptionClassifierRetryPolicy
— почему? Когда у вас все равно есть только одна политика? Он классифицирует исключение, чтобы найти правильную политику, и его классификатор не пересекает цепочку причин. Похоже, вам понадобится пользовательский классификатор исключений вместо карты политики, см.setExceptionClassifier()
.3. В реальном случае мне нужно обрабатывать несколько исключений с разным поведением, что, похоже, довольно часто бывает. Моя единственная проблема с пользовательским классификатором заключается в том, что если api / архитектура spring-retry изменится после обновления до новой версии, у меня возникнет проблема с моей пользовательской логикой. Как вы думаете, является ли это достаточно ценной функцией, чтобы включить ее в саму spring-retry?
4. Да; это относится к spring-retry — я добавил эту возможность в
SimpleRetryPolicy
несколько лет назад. Это также следует добавить в эту политику. Если вы внедряете новый классификатор, которыйextends SubclassClassifier<Throwable, RetryPolicy>
не стесняйтесь отправлять запрос на извлечение. Или я могу взглянуть (после SpringOne), если вы предпочитаете.5. На самом деле, новый классификатор может просто делегировать a
BinaryExceptionClassifier
, поэтому ему не потребуется много логики.