Scheduled 动态刷新
---------------------------------------------------------------------------------------------------------------------------------------------
@Slf4j
@Component
public class WeeklyProjectReportTask {
private static final String LOG_PREFIX = "定时任务 ";
@Resource
private ProjectClient projectClient;
/**
* 每日9点执行定时任务 "0 0 9 * * ?"
*/
@Scheduled(cron = "${schedule.task.cron}")
public void weeklyProjectReport() {
String logPrefix = LOG_PREFIX + "weeklyProjectReport ";
log.info(logPrefix + "开始");
//查询
CommonResult<Object> result = projectClient.retryAllData();
if (!result.getIsSuccess()) {
log.info(logPrefix + "result=" + result.getFailureMessage() + ", 处理失败");
}
log.info(logPrefix + "结束");
}
}
----------------------------------------------------------------修改后-----------------------------------------------------------------------------
@Slf4j
@Component
public class WeeklyProjectReportTask implements Runnable {
private static final String LOG_PREFIX = "Overall project weekly report submission scheduled task ";
@Resource
private ProjectClient projectClient;
@Override
public void run() {
String logPrefix = LOG_PREFIX + "weeklyProjectReport ";
log.info("{}start", logPrefix);
CommonResult<Boolean> result = projectClient.collectProjectBatch();
if (!result.getIsSuccess()) {
log.info("{}process failed, msg={}", logPrefix, result.getFailureMessage());
}
log.info("{}finish", logPrefix);
}
}
-------------------------------------------------------------------修改后--------------------------------------------------------------------------
@Slf4j
@Configuration
@EnableScheduling
@RefreshScope
public class DynamicTaskScheduleConfig implements SchedulingConfigurer {
@Resource
private WeeklyProjectReportTask weeklyProjectReportTask;
private final AtomicReference<ScheduledFuture<?>> weeklyReportTaskHolder = new AtomicReference<>();
private ScheduledTaskRegistrar taskRegistrar;
private ThreadPoolTaskScheduler taskScheduler;
//private static final String DEFAULT_CRON = "0 0 17 ? * 6";
@Value("${schedule.weekly-project-report-task.cron:0 0 17 ? * 6}")
private String nacosCron;
private final AtomicReference<String> currentCron = new AtomicReference<>();
@PostConstruct
public void initTaskScheduler() {
taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(2);
taskScheduler.setThreadNamePrefix("dynamic-task-pool-");
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
taskScheduler.setAwaitTerminationSeconds(10);
taskScheduler.initialize();
// 初始化加载Nacos配置值
currentCron.set(nacosCron);
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
this.taskRegistrar = taskRegistrar;
this.taskRegistrar.setTaskScheduler(taskScheduler);
registerSingleTask(currentCron.get());
log.info("Weekly project weekly report task initialized, default cron:{}", currentCron.get());
}
private void registerSingleTask(String cron) {
CronTrigger cronTrigger = new CronTrigger(cron);
ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(weeklyProjectReportTask, cronTrigger);
weeklyReportTaskHolder.set(scheduledFuture);
log.info("Weekly report task re-registered, new cron expression:{}", cron);
}
public boolean reloadSingleTask(String newCron) {
if (!CronExpression.isValidExpression(newCron)) {
log.warn("Input cron expression {} is invalid, update rejected", newCron);
return false;
}
currentCron.set(newCron);
ScheduledFuture<?> oldFuture = weeklyReportTaskHolder.getAndSet(null);
if (oldFuture != null) {
oldFuture.cancel(true);
log.info("Old weekly report scheduled task cancelled");
}
registerSingleTask(newCron);
return true;
}
public String getCurrentCron() {
return currentCron.get();
}
/**
* Nacos配置自动刷新回调:配置变更自动重启定时
*/
@PostConstruct
public void refreshCronFromNacos() {
// @RefreshScope触发时自动执行,对比新旧配置自动重载
if (!nacosCron.equals(currentCron.get())) {
log.info("Nacos cron config changed, old:{}, new:{}", currentCron.get(), nacosCron);
reloadSingleTask(nacosCron);
}
}
}
----------------------------------------------------------------修改后----------------------------------------------------------------------------
@RestController
@RequestMapping("/inner/schedule/task")
public class InnerScheduleTaskController {
@Resource
private DynamicTaskScheduleConfig dynamicTaskScheduleConfig;
@PostMapping("/update/report-cron")
public CommonResult<Boolean> updateReportCron(@RequestParam String newCron) {
boolean success = dynamicTaskScheduleConfig.reloadSingleTask(newCron);
if (success) {
return CommonResult.success(true, "Cron更新成功");
} else {
return CommonResult.failed("Cron表达式格式错误,更新失败");
}
}
@GetMapping("/current/cron")
public CommonResult<String> getCurrentCron() {
return CommonResult.success(dynamicTaskScheduleConfig.getCurrentCron());
}
}
---------------------------------------------------------------------------------------------------------------------------------------------
@Slf4j
@Configuration
@EnableScheduling
@RefreshScope
public class DynamicTaskScheduleConfig implements SchedulingConfigurer {
@Resource
private WeeklyProjectReportTask weeklyProjectReportTask;
@Value("${schedule.task.cron:0 0 11 ? * 6}")
private String nacosCron;
private final AtomicReference<ScheduledFuture<?>> weeklyReportTaskHolder = new AtomicReference<>();
private ThreadPoolTaskScheduler taskScheduler;
private final AtomicReference<String> currentCron = new AtomicReference<>();
@PostConstruct
public void initTaskScheduler() {
taskScheduler = new ThreadPoolTaskScheduler();
taskScheduler.setPoolSize(2);
taskScheduler.setThreadNamePrefix("dynamic-task-pool-");
taskScheduler.setWaitForTasksToCompleteOnShutdown(true);
taskScheduler.setAwaitTerminationSeconds(10);
taskScheduler.initialize();
// 初始化加载Nacos配置值
currentCron.set(nacosCron);
registerSingleTask(currentCron.get());
log.info("Weekly project weekly report task initialized, cron from nacos:{}", currentCron.get());
}
@Override
public void configureTasks(ScheduledTaskRegistrar taskRegistrar) {
taskRegistrar.setTaskScheduler(taskScheduler);
log.info("Weekly project weekly report task initialized, default cron:{}", currentCron.get());
}
private void registerSingleTask(String cron) {
CronTrigger cronTrigger = new CronTrigger(cron);
ScheduledFuture<?> scheduledFuture = taskScheduler.schedule(weeklyProjectReportTask, cronTrigger);
weeklyReportTaskHolder.set(scheduledFuture);
log.info("Weekly report task re-registered, new cron expression:{}", cron);
}
public boolean reloadSingleTask(String newCron) {
if (!CronExpression.isValidExpression(newCron)) {
log.warn("Input cron expression {} is invalid, update rejected", newCron);
return false;
}
currentCron.set(newCron);
ScheduledFuture<?> oldFuture = weeklyReportTaskHolder.getAndSet(null);
if (oldFuture != null) {
oldFuture.cancel(true);
log.info("Old weekly report scheduled task cancelled");
}
registerSingleTask(newCron);
return true;
}
public String getCurrentCron() {
return currentCron.get();
}
/**
* Bean销毁时释放线程与任务,防止@RefreshScope旧任务残留
*/
@PreDestroy
public void destroy() {
ScheduledFuture<?> oldFuture = weeklyReportTaskHolder.get();
if (oldFuture != null && !oldFuture.isDone()) {
oldFuture.cancel(true);
}
if (taskScheduler != null) {
taskScheduler.shutdown();
log.info("Task scheduler pool shutdown success");
}
}
}
---------------------------------------------------------------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------------------------------------------------------------

浙公网安备 33010602011771号