Java集群实战:单体架构升级到集群架构(一)使用NGINX建立集群
Java集群实战:单体架构升级到集群架构(二)实现session共享
Java集群实战:单体架构升级到集群架构(三)上传文件的共享
Java集群实战:单体架构升级到集群架构(四)使用REDIS分布式锁
Java集群实战:单体架构升级到集群架构(六)分布式缓存REDIS
如果单体架构中有定时任务,当升级到集群时,强烈建议你把定时任务独立出来,只部署一份,让它单独运行。要是集群中存在多个相同定时任务,就等于一个定时任务跑了很多次,天下大乱了!
如果你代码里面的定时任务不好拆分独立出来,那就只好使用一些开源的作业调度框架,比如Quartz。对简单的定时任务,我们也可以使用分布式锁做限制,让相同的任务只执行一次。
GitHub: GitHub - Dengxd/JavaCluster 所有源码都在这里,GitHub经常连不上,要多刷新几次
直接上代码了,一切尽在代码和注释中:
//每天一点钟执行
@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();//释放锁
}
}