想要在 Spring 批处理中为事务实现指数退避
Want to implement exponentialbackoff for a transaction in Spring Batch
基本上是标题。我正在使用 JDBC 项目 reader 和 JDBC 项目编写器,我正在使用 API 通过处理器更改特定状态,如果 API无法更改状态,我想稍后使用指数退避重试。我不知道如何实现这个
你有两个选择:
1。在您的项目处理器中手动处理重试操作
基本上有两种方法可以通过编程方式或声明方式实现。
1.1 程序化方法
您首先根据需要使用退避策略定义重试模板:
@Bean
public RetryTemplate retryTemplate() {
// configure backoff policy
ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
exponentialBackOffPolicy.setInitialInterval(1000);
exponentialBackOffPolicy.setMultiplier(2.0);
exponentialBackOffPolicy.setMaxInterval(10000);
// configure retry policy
SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
simpleRetryPolicy.setMaxAttempts(5);
// configure retry template
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);
retryTemplate.setRetryPolicy(simpleRetryPolicy);
return retryTemplate;
}
然后在您的项目处理器中使用该重试模板:
import org.springframework.batch.item.ItemProcessor;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.support.RetryTemplate;
public class MyRetryableItemProcessor implements ItemProcessor {
RetryTemplate retryTemplate;
public MyRetryableItemProcessor(RetryTemplate retryTemplate) {
this.retryTemplate = retryTemplate;
}
@Override
public Object process(Object item) throws Exception {
return retryTemplate.execute(new RetryCallback<Object, Exception>() {
@Override
public Object doWithRetry(RetryContext retryContext) throws Exception {
// API call
return item;
}
});
}
}
1.2 使用注释的声明式方法
这是一个例子:
import org.springframework.batch.item.ItemProcessor;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyAnnotationBasedRetryableItemProcessor implements ItemProcessor {
@Override
@Retryable(backoff = @Backoff(delay = 1000L, maxDelay = 10000, multiplier = 2.0))
public Object process(Object item) throws Exception {
// Do API call
return item;
}
}
2。使用 fault-tolerant 步骤
让 Spring 批处理为您处理重试
在这种情况下,您可以在 fault-tolerant 步骤中设置自定义 RetryPolicy
:
@Bean
public Step step(StepBuilderFactory stepBuilderFactory) {
// configure backoff policy
ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
exponentialBackOffPolicy.setInitialInterval(1000);
exponentialBackOffPolicy.setMultiplier(2.0);
exponentialBackOffPolicy.setMaxInterval(10000);
// configure retry policy
SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
simpleRetryPolicy.setMaxAttempts(5);
return stepBuilderFactory.get("myStep")
.<Integer, Integer>chunk(5)
.reader(itemReader())
.processor(itemProcessor())
.writer(itemWriter())
.faultTolerant()
.retryPolicy(simpleRetryPolicy)
.build();
}
请注意,在这种情况下,每当您的处理器为某个项目抛出异常时,整个块都会逐项重试(每个项目将 re-processed 在其自己的事务中)。
上面的示例使用了 spring-retry,因为您提到过您对此有偏好。但同样的想法可以应用于任何其他 fault-tolerance 库。
基本上是标题。我正在使用 JDBC 项目 reader 和 JDBC 项目编写器,我正在使用 API 通过处理器更改特定状态,如果 API无法更改状态,我想稍后使用指数退避重试。我不知道如何实现这个
你有两个选择:
1。在您的项目处理器中手动处理重试操作
基本上有两种方法可以通过编程方式或声明方式实现。
1.1 程序化方法
您首先根据需要使用退避策略定义重试模板:
@Bean
public RetryTemplate retryTemplate() {
// configure backoff policy
ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
exponentialBackOffPolicy.setInitialInterval(1000);
exponentialBackOffPolicy.setMultiplier(2.0);
exponentialBackOffPolicy.setMaxInterval(10000);
// configure retry policy
SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
simpleRetryPolicy.setMaxAttempts(5);
// configure retry template
RetryTemplate retryTemplate = new RetryTemplate();
retryTemplate.setBackOffPolicy(exponentialBackOffPolicy);
retryTemplate.setRetryPolicy(simpleRetryPolicy);
return retryTemplate;
}
然后在您的项目处理器中使用该重试模板:
import org.springframework.batch.item.ItemProcessor;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.support.RetryTemplate;
public class MyRetryableItemProcessor implements ItemProcessor {
RetryTemplate retryTemplate;
public MyRetryableItemProcessor(RetryTemplate retryTemplate) {
this.retryTemplate = retryTemplate;
}
@Override
public Object process(Object item) throws Exception {
return retryTemplate.execute(new RetryCallback<Object, Exception>() {
@Override
public Object doWithRetry(RetryContext retryContext) throws Exception {
// API call
return item;
}
});
}
}
1.2 使用注释的声明式方法
这是一个例子:
import org.springframework.batch.item.ItemProcessor;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.stereotype.Component;
@Component
public class MyAnnotationBasedRetryableItemProcessor implements ItemProcessor {
@Override
@Retryable(backoff = @Backoff(delay = 1000L, maxDelay = 10000, multiplier = 2.0))
public Object process(Object item) throws Exception {
// Do API call
return item;
}
}
2。使用 fault-tolerant 步骤
让 Spring 批处理为您处理重试在这种情况下,您可以在 fault-tolerant 步骤中设置自定义 RetryPolicy
:
@Bean
public Step step(StepBuilderFactory stepBuilderFactory) {
// configure backoff policy
ExponentialBackOffPolicy exponentialBackOffPolicy = new ExponentialBackOffPolicy();
exponentialBackOffPolicy.setInitialInterval(1000);
exponentialBackOffPolicy.setMultiplier(2.0);
exponentialBackOffPolicy.setMaxInterval(10000);
// configure retry policy
SimpleRetryPolicy simpleRetryPolicy = new SimpleRetryPolicy();
simpleRetryPolicy.setMaxAttempts(5);
return stepBuilderFactory.get("myStep")
.<Integer, Integer>chunk(5)
.reader(itemReader())
.processor(itemProcessor())
.writer(itemWriter())
.faultTolerant()
.retryPolicy(simpleRetryPolicy)
.build();
}
请注意,在这种情况下,每当您的处理器为某个项目抛出异常时,整个块都会逐项重试(每个项目将 re-processed 在其自己的事务中)。
上面的示例使用了 spring-retry,因为您提到过您对此有偏好。但同样的想法可以应用于任何其他 fault-tolerance 库。