The timed task in a set of code is run by multiple machines, and the data is easy to increase or increase in size. Distributed locks, code execution time

The timed task in a set of code is run by multiple machines, and the data is easy to increase or increase in size. Distributed locks, code execution time
During development, we encountered a scenario where the same set of code runs on multiple machines. The strange thing is that the database tables are all the same. Due to business needs, many timed tasks have been written to process data in batches. However, during the running process, it was found that when multiple machines run the same set of codes at the same time to operate the same table on the same data source, the data that comes out will be larger than the official data, or more. At this time, I thought of using Lock.
But a simple lock can only lock the problem of concurrent request threads when only one machine is running ( scheduled tasks can not only run regularly but also be manually triggered to run ). It can't solve the problem, and distributed locks are used at this time. Distributed locks of redis can be used.
Steps, the code is as follows, not much explanation

<dependency>
   <groupId>org.redisson</groupId>
   <artifactId>redisson</artifactId>
   <version>3.16.3</version>
   -- 版本按自己需求
</dependency>

Step 1: Injection (if there is no redis dependency)
insert image description here
Step 2: Use in code

@Scheduled(cron = "0 59 23 * * ?")
    public void stockAllCityJob(){
    
    
        String lockey = "stockAllCityJob_stockExchange_lock";
        RLock lock = redissonClient.getLock(lockey);
        long starttime = System.currentTimeMillis();
        try {
    
    
            if(!lock.tryLock(0,10, TimeUnit.MINUTES)){
    
    
                log.warn("获取任务锁失败,退出。");
                return;
            }
            log.info("==================================定时任务开始=========================================================");
            //业务代码放在这里
            log.info("==================================定时任务结束=========================================================");
            
            long endtime = System.currentTimeMillis();
            long end =  endtime- starttime;
            System.out.println("定时任务执行时间:"+end / 1000 / 60 / 60 + "时" + end / 1000 / 60 % 60 + "分" + end / 1000 % 60 + "秒");

        } catch (InterruptedException e) {
    
    
            log.warn("获取任务锁异常,退出。");
            return;
        }finally {
    
    
            if(lock.isLocked() && lock.isHeldByCurrentThread()){
    
    
                lock.unlock();
                log.info(Thread.currentThread().getName() + "unlock");
            }
        }

    }

After adding distributed locks, no matter how many machines and threads run at the same time, only the task that first grabs the thread to get the lock can run in the end.

====renew=
There is another way to solve this kind of problem, that is: when the code runs the scheduled task on multiple machines, you can specify which server ip the scheduled task can run on. This
can also solve similar data problems.
The method of obtaining the current server ip is as follows
insert image description here
The specific code:

public static void main(String[] args) {
    
    

        try {
    
    
            String hostAddress = InetAddress.getLocalHost().getHostAddress();
            System.out.println(hostAddress);
        } catch (UnknownHostException e) {
    
    
            e.printStackTrace();
        }
    }

Note: This method is only a personal idea and has not been verified by the actual project. It is only for reference if necessary.

おすすめ

転載: blog.csdn.net/weixin_51114236/article/details/125991240