最近在公司呢,有一个需求,大概意思就是需要我去调用远程接口,但如果出现异常或者响应失败的时候,就需要开启重试机制,直到返回成功的响应为止。我很疑惑,按理说这种情况通常都应该有一个最大重试次数吗?最终在我像组长确认这个需求之后,还是要求我按照原本需求来,那我没办法了。
然后就开始分析,发现这个业务需要手动的开启与停止,所以就想到了使用ThreadPoolTaskScheduler
这个Spring的任务调度器。
ThreadPoolTaskSchedule的优点:
线程池管理
: ThreadPoolTaskScheduler 使用线程池来管理任务的执行。线程池中的线程可以异步地执行任务,从而提高应用程序的性能和并发能力。这样,任务可以并发地执行,而不会阻塞主线程或其他任务的执行。任务调度
: ThreadPoolTaskScheduler 允许您按照指定的时间间隔或固定的时间点来调度任务的执行。您可以创建周期性的任务或者一次性的任务,并指定任务的执行时间。灵活的配置
: ThreadPoolTaskScheduler 具有灵活的配置选项,您可以根据应用程序的需求进行调整。您可以设置线程池的大小、任务队列、线程命名前缀等。异常处理
: ThreadPoolTaskScheduler 允许您定义任务执行过程中的异常处理逻辑。如果任务执行过程中抛出了异常,您可以通过合适的异常处理策略来处理异常,例如记录日志或进行报警。集成 Spring 框架
: ThreadPoolTaskScheduler 是 Spring 框架的一部分,因此可以轻松地集成到 Spring 应用程序中。您可以使用 Spring 的依赖注入来获取 ThreadPoolTaskScheduler 实例,并在应用程序中使用。线程安全
: ThreadPoolTaskScheduler 负责管理任务的调度和执行,确保在多线程环境下的线程安全性。
ThreadPoolTaskSchedule一些API
-
schedule(Runnable task, Trigger trigger)
: 调度一个任务在满足指定的触发条件时执行。 -
scheduleAtFixedRate(Runnable task, long period)
: 创建一个以固定速率执行任务的调度。 -
scheduleAtFixedRate(Runnable task, Date startTime, long period)
: 创建一个在指定时间开始,然后以固定速率执行任务的调度。 -
scheduleWithFixedDelay(Runnable task, long delay)
: 创建一个以固定延迟执行任务的调度。 -
scheduleWithFixedDelay(Runnable task, Date startTime, long delay)
: 创建一个在指定时间开始,然后以固定延迟执行任务的调度。 -
scheduleAtCronExpression(Runnable task, String cronExpression)
: 使用 Cron 表达式调度任务执行。
下面就是我在项目中如何应用的:
配置ThreadPoolTaskSchedule
@Configuration
@EnableAsync
public class ThreadPoolConfig {
@Bean
public ThreadPoolTaskScheduler threadPoolTaskScheduler(){
ThreadPoolTaskScheduler taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(10);
taskScheduler.setThreadNamePrefix("schedule-executor-");
//满了调用线程执行,认为重要任务
taskScheduler.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
taskScheduler.initialize();
return taskScheduler;
}
}
创建手动开启关闭的方法
@Component
@Slf4j
public class HelloSchedule {
private final ThreadPoolTaskScheduler taskScheduler;
@Autowired
public FaultyTrafficLightSchedule(ThreadPoolTaskScheduler taskScheduler) {
this.taskScheduler = taskScheduler;
}
private ScheduledFuture<?> scheduledFuture;
private AtomicInteger retryCount = new AtomicInteger(0);
// 手动启动定时任务
public void startTask(String cron) {
log.info("【HelloSchedule】 startTask ......");
if (scheduledFuture == null || scheduledFuture.isCancelled()) {
Runnable task = () -> {
int currentRetryCount = retryCount.incrementAndGet();
log.info("【HelloSchedule】 第 {} 次重试",currentRetryCount);
// 这里就是你需要定时去做的内容
...
// 判断满足什么条件的时候去关闭这个定时任务,就比如说这里重试五次之后就停止定时任务
if (currentRetryCount == 5) {
// 结束
stopTask();
}
};
scheduledFuture = taskScheduler.schedule(task, new CronTrigger(cron));
}
}
// 手动停止定时任务
public void stopTask() {
if (scheduledFuture != null) {
log.info("【HelloSchedule】 stopTask ......");
scheduledFuture.cancel(true);
}
}
}