利用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;
        }
    }
}

 

posted @ 2020-03-30 12:57  panchanggui  阅读(795)  评论(0编辑  收藏  举报