If there are scheduled tasks in the monolithic architecture, when upgrading to a cluster, it is strongly recommended that you separate the scheduled tasks, deploy only one copy, and let it run independently. If there are multiple identical scheduled tasks in the cluster, it means that one scheduled task has run many times, and the world is in chaos!
If the timing tasks in your code are not easy to separate and separate, you have to use some open source job scheduling frameworks , such as Quartz. For simple timed tasks, we can also use distributed locks to limit the execution of the same task only once.
GitHub: GitHub - all the source code of Dengxd/JavaCluster is here, GitHub often cannot be connected, so it needs to be refreshed several times
Go directly to the code, everything is in the code and comments:
//每天一点钟执行
@Scheduled(cron ="0 0 1 * * ?")
public void index() {
RLock lock = redissonClient.getLock("MyTaskOne");//建立锁
try {
lock.lock();//锁住资源
//先判断定时任务是否被集群中的其他服务器执行了,
//其他服务器执行完定时任务,会在REDIS中加一个key-value标志
// key=MyTaskOne:当天日期, 比如MyTaskOne:20230319
// value=Done
SimpleDateFormat sdf=new SimpleDateFormat("yyyyMMdd");
String back=sdf.format(new Date());
String key="MyTaskOne:"+back;
RBucket<Object> bucket = redissonClient.getBucket(key);
String str = (String)bucket.get();
//如果key已经被其他服务器写入Done, 说明这个定时任务已经被别人做了
if(str!=null && str.equals("Done")){
return ;
}
//开始定时任务
System.out.println("execute MyTaskOne");
//定时任务执行完成
//把Done写入redis
bucket.set("Done",365, TimeUnit.DAYS);
} catch (Exception e) {
e.printStackTrace();
}finally {
lock.unlock();//释放锁
}
}