基于Redis实现分布式锁,避免重复执行定时任务

本文介绍了一种在Spring框架下防止定时任务在集群环境中重复执行的方法。通过在Redis中设置锁并结合时间戳判断,有效地避免了定时任务的重复执行问题。此方案适用于任务间隔较长且集群规模较小的应用场景。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Spring提供了定时任务的功能,但是在多个实例的集群中,会出现定时任务重复执行多次的情况。

使用Qutaz框架自带的分布式定时任务可以很好的解决这个问题,但是讲道理功能有些过于强大,对于需求不高,乃至可以一定程度上允许失误的简单任务中,性价比比较低。

使用task任务时,可以通过在redis等缓存、数据库中创建锁来实现避免重复执行任务的功能。

基本思路如下:

  • 在redis中设置一个key作为锁,值为时间戳
  • 尝试用setnx方法直接设置锁,若成功则直接执行任务。
  • 若设置失败,使用getset方法获取当前锁并更新时间戳
  • 若获取的时间戳在有效期内,则不执行任务,否则执行任务

当然这种实现方法是很粗糙的。对于高并发的频繁定时任务处理很不完美。若执行失败也会导致任务丢失。

本方案实现的处理场景是间隔比较长的数据处理定时任务。服务器集群也只有三个节点,上线运行效果良好。

简要实现代码如下:

private boolean getLock(String key){
        String syncKey = "sync_lock_"+key;
        long curr = System.currentTimeMillis();
        String time = curr+"";
        long has = redisTemplate.setnx(syncKey,time);
        if(has == 1){
            return true;
        }else{
            String lock = redisTemplate.getSet(syncKey,time);
            if(lock == null){
                return true;
            }else{
                long l = NumberUtils.toLong(lock);
                //三十秒以内都算有效锁
                return Math.abs(curr-l)<30000;
            }
        }
    }
复制代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值