利用redis 分布式鎖 解決集群環境下多次定時任務執行


定時任務:

    @Scheduled(cron= "0 39 3 * * *")
    public void getAllUnSignData(){
        //檢查任務鎖,若其它節點的相同定時任務已經執行,則該節點的任務執行一個空任務,否則設置鎖並執行該任務
        String timerName = this.getClass().getName()+Thread.currentThread() .getStackTrace()[1].getMethodName();//當前類名+當前方法名
        if(redisLock.requireLock(timerName,7200)){
            return;
        }
        long startTime = System.currentTimeMillis();
        logger.info("定時任務 UnSignStatistics start-->" + startTime );
        //找出簽到異常的學生,保存在表中
        gxyWarnService.saveUnSignWarn();
        long endTime = System.currentTimeMillis();
        logger.info("定時任務 UnSignStatistics end-->" +endTime+ ", execute time: " + (endTime - startTime) + "ms" );


    }

用類名+方法名作為key, 去redis 獲取鎖。

如果獲取到了鍵值對: (key , 1) ,則說明定時任務已被執行,返回true , 執行if 中的return, 不執行 后面的定時任務。

如果沒有獲取到 鍵值對: (key , 1) ,則說明定時任務沒有被執行 。在redis中 設置鍵值對 (key , 1), (並設置有效期7200秒,這個有效期小於定時任務的周期即可),並返回false 。不執行if 中的return,繼續執行后面的定時任務代碼。

 

 

 

@Component
public class RedisLock {
    //redis中存任務鎖的key前綴
    public final static String MOGUDING_TIMER_LOCK_KEY = "com:lock:job:";

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 判斷是否有鎖。有,返回true;否,返回false,設置一定期效的鎖
     * @param lockName
     * @param expire  鎖的有效時間長,單位:秒
     * @return
     */
    public boolean requireLock(String lockName,long expire){
        String key = MOGUDING_TIMER_LOCK_KEY+lockName;
        if(redisTemplate.opsForValue().getAndSet(key,"1")==null){   //“1”這里無任何意義
            redisTemplate.expire(key,expire,TimeUnit.SECONDS);
            return false;
        }else {
            return true;
        }
    }
    /**
     * 判斷是否有鎖。有,返回true;否,返回false,設置一定期效的鎖
     * @param lockName
     * @param date  鎖的有效時間截止點
     * @return
     */
    public boolean requireLock(String lockName,Date date){
        String key = MOGUDING_TIMER_LOCK_KEY+lockName;
        if(redisTemplate.opsForValue().getAndSet(key,"1")==null){  //“1”這里無任何意義
            redisTemplate.expireAt(key,date);
            return false;
        }else {
            return true;
        }
    }
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM