redis setnx解决定时任务多节点部署并发问题(分布式锁)

版权声明:本文为博主原创文章,转载需注明出处。 https://blog.csdn.net/david_pfw/article/details/86287406

在一些大的互联网平台,通常都会使用定时任务处理一些周期性的业务,而为了保障系统的高可用性,定时任务也会多节点部署,而解决多节点并发问题(分布式锁),大家通常会想到使用缓存,如redis,但是如果使用set / get是无法解决问题的,同样会出现并发问题,redis有专门的解决分布式并发问题的方法,就是setnx命令,很好用,下面介绍一下java实现redis分布式锁的方法。

1. Redis SETNX命令语法:

SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写,其操作为:将 key 的值设为 value ,当且仅当 key 不存在。若给定的 key 已经存在,则 SETNX 不做任何动作。
返回值:
  设置成功,返回 1 。
  设置失败,返回 0 。

 SetNX 不具备设置过期时间的功能,所以我们需要借助 Expire 来设置,否则可能会出现死锁问题。

2. 环境说明

是基于 spring boot的项目,这是一个项目中多节点定时扣费任务的实现。

3. 配置实现

3.1. 定时任务

@Component
@EnableScheduling
public class QuartzCharge {
	Logger logger = LogManager.getLogger("quartzCharge");
	@Autowired
	RedisComponent redisComponent;
	
	
	 //每每小时0分0秒执行一次
     @Scheduled(cron = "0 0 * * * *")
	 public void quartzCharge(){
		 //需要先查询redis的计费标记,如果有,就不计费,如果没有就计费,整点计费
		 logger.info(" 定时计费开始: ");
		 //redis分布式锁,尽量要设置过期时间,防止死锁
		 if(!redisComponent.setNX("quartzChargeTag", "1", 10, TimeUnit.SECONDS)){
			 logger.info("已有执行中定时扣费任务,本次不执行!");
			 return;
		 }
		 
		 //计费
		 try{
			 //to_do 定时业务实现
             
		 }catch(Exception e){
			 logger.error("定时扣费异常结束: " + e);
		 }finally{
			//任务执行完,一定要清空缓存,防止意外终止死锁
			 redisComponent.del("quartzChargeTag");
		 }
		 
		 logger.info("定时计费结束!");
	 }

}

3.2.redis操作工具类

@Component
public class RedisComponent {
	@Autowired
	//操作字符串的template,StringRedisTemplate是RedisTemplate的一个子集
	private StringRedisTemplate stringRedisTemplate;
	@Autowired
	// RedisTemplate,可以进行所有的操作  
	private RedisTemplate<Object,Object> redisTemplate;
	
	
	/*
	 * redis分布式锁实现,同时利用expire设置过期时间
     * 返回true就是设置成功
	 * */
	public Boolean setNX(String key, String value,long timeout, TimeUnit unit){
		Boolean isExit = this.redisTemplate.getConnectionFactory().getConnection().setNX(key.getBytes(), value.getBytes());
		//如果设置成功,要设置其过期时间
        if(isExit){
			redisTemplate.expire(key, timeout, unit);
		}
		return isExit;
	}
	
}

3.3 双节点执行效果

节点一日志:

节点二日志:

看两个节点的日志,可以清楚的看到,两个节点相互执行定时任务,执行时间就在毫厘之间,谁快谁就抢到锁,一个节点挂了还有另外一个,这样就保障了系统的高可用,是不是挺酸爽的,O(∩_∩)O哈哈~

----------over--------------

猜你喜欢

转载自blog.csdn.net/david_pfw/article/details/86287406