Spring retry 如何使用Spring Retry包装耗尽重试时的异常
上下文: 我正在使用spring重试来重试restTemplate调用 restTemplate调用是从kafka侦听器调用的。 kafka侦听器还配置为在出错时重试(如果在该过程中引发任何异常,而不仅仅是restTemplate调用) 目标: 我想防止kafka在错误来自已耗尽的重试模板时重试 实际行为: 当retryTemplate用尽所有重试次数时,将引发原始异常。从而阻止我识别retryTemplate是否重试了错误 期望的行为: 当retryTemplate用尽所有重试次数时,将原始异常包装在RetryExtustedException中,这将允许我将其从kafka重试中列入黑名单 问题: 我怎么能做这样的事 谢谢 编辑 RetryTemplate配置:Spring retry 如何使用Spring Retry包装耗尽重试时的异常,spring-retry,Spring Retry,上下文: 我正在使用spring重试来重试restTemplate调用 restTemplate调用是从kafka侦听器调用的。 kafka侦听器还配置为在出错时重试(如果在该过程中引发任何异常,而不仅仅是restTemplate调用) 目标: 我想防止kafka在错误来自已耗尽的重试模板时重试 实际行为: 当retryTemplate用尽所有重试次数时,将引发原始异常。从而阻止我识别retryTemplate是否重试了错误 期望的行为: 当retryTemplate用尽所有重试次数时,将原始异
RetryTemplate retryTemplate = new RetryTemplate();
FixedBackOffPolicy backOffPolicy = new FixedBackOffPolicy();
backOffPolicy.setBackOffPeriod(1000);
retryTemplate.setBackOffPolicy(backOffPolicy);
Map<Class<? extends Throwable>, Boolean> retryableExceptions = new HashMap<>();
retryableExceptions.put(FunctionalException.class, false);
SimpleRetryPolicy retryPolicy = new SimpleRetryPolicy(3, retryableExceptions, true, true);
retryTemplate.setRetryPolicy(retryPolicy);
retryTemplate.setThrowLastExceptionOnExhausted(false);
RetryTemplate RetryTemplate=new RetryTemplate();
FixedBackOffPolicy backOffPolicy=新的FixedBackOffPolicy();
退避政策。退避期(1000);
retryTemplate.setBackOffPolicy(backOffPolicy);
映射只需使用配置为将retryExhustedException
分类为不可重试的simpleRetryPolicy
配置侦听器重试模板
由于容器将所有侦听器异常包装在ListenerExecutionFailedException
中,因此请确保将TraverseCaues
属性设置为true
/**
* 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. The default value indicates whether to retry or not for exceptions
* (or super classes) are not found in the map.
*
* @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 clause traversable
* @param defaultValue the default action.
*/
public SimpleRetryPolicy(int maxAttempts, Map<Class<? extends Throwable>, Boolean> retryableExceptions,
boolean traverseCauses, boolean defaultValue) {
我已经将带有TraverseCaues的SimpleRetryPolicy配置为true。但这是抛出原始异常,然后将其封装在LEFE中。我想要的是触发RetryExhaustedException,而不是原始异常。如果(thrownException instanceof RetryExhustedException)在ErrorHandler中,您需要编辑问题并显示代码,那么我可以这样做-容器无法从链的顶部剥离您的RetryExhustedException
-它对侦听器异常一无所知。我想你是从你的恢复回拨中抛出的。如果没有恢复回调,模板将抛出一个ExhustedRetryException
包装原始异常,除非您已将ThrowLasteExceptionNext
设置为true,这将导致您描述的行为。编辑了我的问题,但是throwlastexceptionnexhausted并没有被使用,因为RetryTemplate类中的状态为null——得到了;很抱歉在这种情况下,您应该在execute()
中添加一个恢复回调,并将包装器扔到那里。我用一个例子编辑了我的答案。请注意,如果需要,您可以使用context.setAttribute(…)将任意信息从RetryCallback
传递到RecoveryCallback
代码>。
@KafkaListener
public void onMessage(ConsumerRecord<String, String> record) {
retryTemplate.execute((args) -> {
throw new RuntimeException("Should be catched by ErrorHandler to prevent rollback");
}
throw new RuntimeException("Should be retried by afterRollbackProcessor");
}
/**
* 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. The default value indicates whether to retry or not for exceptions
* (or super classes) are not found in the map.
*
* @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 clause traversable
* @param defaultValue the default action.
*/
public SimpleRetryPolicy(int maxAttempts, Map<Class<? extends Throwable>, Boolean> retryableExceptions,
boolean traverseCauses, boolean defaultValue) {
template.execute((args) -> {...}, (context) -> throw new Blah(context.getLastThrowable()));