Java Cluster Combat: Upgrading Single Architecture to Cluster Architecture (5) Scheduled Tasks

Java Cluster Combat: Upgrading Single Architecture to Cluster Architecture (1) Using NGINX to Build a Cluster

Java Cluster Combat: Upgrading Single Architecture to Cluster Architecture (2) Realizing Session Sharing

Java cluster combat: single architecture upgrade to cluster architecture (3) sharing of uploaded files

Java Cluster Combat: Upgrading Single Architecture to Cluster Architecture (4) Using REDIS Distributed Locks

Java Cluster Combat: Upgrading Single Architecture to Cluster Architecture (6) Distributed Cache REDIS

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();//释放锁
    }


}
 

Guess you like

Origin blog.csdn.net/dengxiaodai/article/details/129707851