redis分布式锁解决schedule集群重复执行问题

redis分布式锁解决schedule集群重复执行问题

   点关注不迷路,欢迎再访!		

应用场景

集群下部署多个应用,定时任务就会出现重复执行的问题,为了避免资源浪费和脏数据的问题出现,借助redis分布式锁解决

redis分布式锁实现

基于Redis实现的分布式锁其实很简单,底层就是使用redis的setnx指令来实现的加锁,我们来看看官方对setnx的定义:
SETNX key value
将 key 的值设为 value ,当且仅当 key 不存在。
若给定的 key 已经存在,则 SETNX 不做任何动作。

死锁问题

既然setnx这么强大,还需考虑一些极端场景。
比如如果一台机器在运行状态中突然宕机没有设置锁的过期时间无法自动释放锁,那么另一台应用会一直认为有机器占用着分布式锁执行任务,此时实际是没有执行的,而导致死锁问题。

死锁问题解决方法

在这里我们给分布式锁设置一个过期时间,能够在开始执行任务后自动释放分布式锁

具体实现代码

/**
 * @author ex_sunqi
 * 分布式锁控制schedule
 */
@Component
@Configuration
@EnableScheduling
public class fileScheduleTask {
	    
	private final Log logger = LogFactory.getLog(getClass());	  
	private static final String LOCK = "job-lock";
    private static final String KEY = "fileTasklock";
    //单位为秒  默认10分钟
    private long redis_time = 60 * 10;

	    @Scheduled(cron = "0 0/30 * * * ?")
	    public void fileConvertJob() {
	        boolean lock = false;
	        try {
	            lock = redisTemplate.opsForValue().setIfAbsent(KEY, LOCK);
	            logger.info("是否获取到锁:" + lock);
	            if (lock) {
	            	//设置分布式锁的过期时间
                    redisTemplate.expire(KEY, redis_time , TimeUnit.SECONDS);
	            	//代码核心逻辑  
	            	      		
	            } else {
	                logger.info("没有获取到锁,不执行任务!");
	                return;
	            }
	        } finally {
	            if (lock) {
	                redisTemplate.delete(KEY);
	                logger.info("任务结束,释放锁!");
	            } else {
	                logger.info("没有获取到锁,无需释放锁!");
	            }
	        }

	    }
}

发布了101 篇原创文章 · 获赞 33 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qq_39443053/article/details/103542774