package cn.besteam.common.job; import cn.besteam.common.util.RedisUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.util.StopWatch; /** * @author chenbo@guworks.cc * @title redis分布式锁/任务, 子类负责初始化ICacheService * @date 2018年07月17日 * @since v1.0.0 */ public abstract class AbstractRedisLockJob { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired protected RedisUtil redisUtil; /** * 锁的键值 */ protected String lockKey = "medical-common-lock-key"; /** * 锁的过期时间,单位:秒 * 在锁过期时间内完成任务, 并须配合重复任务的时间间隔 */ protected int expireSeconds = 60 * 60; /** * setNx 获取锁 */ public void doJob() { logger.info("job开始,尝试获取分布式锁: {}", lockKey); boolean locked = false; try { // locked = redisUtil.lock(lockKey, expireSeconds); if (locked) { logger.info("分布式锁获取成功: {}, 锁过期时间: {}秒", lockKey, expireSeconds); doProcess(); } else { logger.info("分布式锁获取失败, key={}, 表示有其他实例正在执行该任务", lockKey); } } catch (Exception e) { logger.error("job执行异常", e); // 如果异常发生在异步任务启动前,需要释放锁 if (locked) { try { redisUtil.del(lockKey); logger.info("异常情况下分布式锁释放成功: {}", lockKey); } catch (Exception ex) { logger.error("异常情况下分布式锁释放异常: {}", lockKey, ex); } } } } private void doProcess() { logger.info("获取到锁后,开始异步执行任务: {}, 线程ID: {}", lockKey, Thread.currentThread().getId()); StopWatch stopWatch = new StopWatch(); stopWatch.start(); try { process(); } catch (Exception e) { logger.error("任务执行异常", e); } finally { // 任务执行完成后释放锁 try { redisUtil.del(lockKey); logger.info("任务完成,分布式锁释放成功: {}", lockKey); } catch (Exception e) { logger.error("任务完成,分布式锁释放异常: {}", lockKey, e); } } stopWatch.stop(); logger.info("job耗时: {} 毫秒", stopWatch.getTotalTimeMillis()); } protected abstract void process(); }