基于Mongodb分布式锁解决定时任务并发执行问题

 更新时间:2023年04月20日 09:21:06   作者:蒲公英的狂想  
这篇文章主要介绍了基于Mongodb分布式锁解决定时任务并发执行问题,网上有很多分布式锁的实现方案,基于redis、zk、等有很多,但是我的就是一个用了mysql和mongo的小应用,本文给大家详细讲解,需要的朋友可以参考下
(福利推荐:【腾讯云】服务器最新限时优惠活动,云服务器1核2G仅99元/年、2核4G仅768元/3年,立即抢购>>>:9i0i.cn/qcloud

(福利推荐:你还在原价购买阿里云服务器?现在阿里云0.8折限时抢购活动来啦!4核8G企业云服务器仅2998元/3年,立即抢购>>>:9i0i.cn/aliyun

前言

我们日常开发过程,会有一些定时任务的代码来统计一些系统运行数据,但是我们应用有需要部署多个实例,传统的通过配置文件来控制定时任务是否启动又太过繁琐,而且还经常出错,导致一些异常数据的产生

网上有很多分布式锁的实现方案,基于redis、zk、等有很多,但是我的就是一个用了mysql和mongo的小应用,不准备引入其他三方中间件来解决这个问题,撸一个简单的分布式锁来解决定时任务并发执行的问题,加锁操作的原子性和防死锁也都要支持,这里我使用mongodb写了AllInOne的工具类

All in one Code

先上代码

@Component
@Slf4j
public class MongoDBLock {

    private static final int DEFAULT_LOCK_TIMEOUT = 30;//锁的默认超时时间,单位秒

    private MongoTemplate mongoTemplate;
    private int lockTimeout;

    public MongoDBLock(MongoTemplate mongoTemplate) {
        this.mongoTemplate = mongoTemplate;
        this.lockTimeout = DEFAULT_LOCK_TIMEOUT;
    }

    /**
     * 尝试获取分布式锁
     *
     * @param lockKey 锁的key
     * @return true:获取锁成功,false:获取锁失败
     */
    private boolean acquireLock(String lockKey) {
        LockDocument document = new LockDocument();
        document.setId(lockKey);
        document.setExpireAt(Instant.ofEpochMilli(Instant.now().toEpochMilli() + lockTimeout * 1000));
        try {
            mongoTemplate.insert(document);
            return true;
        } catch (Exception e) {

        }
        return false;
    }

    /**
     * 释放分布式锁
     *
     * @param lockKey 锁的key
     */
    private void releaseLock(String lockKey) {
        Query query = new Query(Criteria.where("key").is(lockKey));
        mongoTemplate.remove(query, LockDocument.class);
        log.info("程序执行成功,释放分布式锁,lockKey:{}",lockKey);
    }

    /**
     * 分布式锁入口方法,参数lockName为锁的名称,lockKey为需要加锁的key,执行完成后自动释放锁
     *
     * @param lockKey
     * @param task
     * @param <T>
     * @throws Exception
     */
    public <T> void executeWithLock(String lockKey, ITask<T> task) throws Exception {
        boolean locked = acquireLock(lockKey);
        if (locked) {
            log.info("获取分布式锁成功,lockKey:{}",lockKey);
            try {
                task.execute();
            } finally {
                releaseLock(lockKey);
            }
        } else {
            log.warn("获取分布式锁失败,lockKey:{}", lockKey);
            throw new AppException("获取分布式锁失败!");
        }
    }

    @Data
    @Document(collection = "lock_collection")
    static class LockDocument {
        @Id
        private String id;
        @Indexed(expireAfterSeconds = DEFAULT_LOCK_TIMEOUT)
        private Instant expireAt;
    }

    @FunctionalInterface
    public interface ITask<T> {
        T execute() throws Exception;
    }
}

调用示例

    @Resource
    MongoDBLock mongoDBLock;

    mongoDBLock.executeWithLock("key", () -> {
        // do some thing
        return null;
    });

原理

  • 使用key作为主键,利用mongodb的insert原子性保障LockDocument不会重复插入
  • LockDocument中expireAt字段利用的mongodb索引过期机制,解决死锁问题,这里设置超时时间是30秒,并在执行完成之后会主动释放锁

到此这篇关于基于Mongodb分布式锁简单实现,解决定时任务并发执行问题的文章就介绍到这了,更多相关Mongodb分布式锁内容请搜索程序员之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持程序员之家!

相关文章

  • CentOS 6.5 x64系统中安装MongoDB 2.6.0二进制发行版教程

    CentOS 6.5 x64系统中安装MongoDB 2.6.0二进制发行版教程

    这篇文章主要介绍了CentOS 6.5 x64系统中安装MongoDB 2.6.0二进制发行版教程,本文分为6个步骤完成MongoDB的安装和启动,需要的朋友可以参考下
    2015-01-01
  • MongoDB教程之数据操作实例

    MongoDB教程之数据操作实例

    这篇文章主要介绍了MongoDB教程之数据操作实例,本文讲解了批量插入、数据库清除、数据更新、修改器、数组修改器、upsert等内容,需要的朋友可以参考下
    2015-05-05
  • Mac下安装配置mongodb并创建用户的方法

    Mac下安装配置mongodb并创建用户的方法

    最近在在学习nodejs,相比mysql,mongodb与nodejs搭配更合适,存储数据格式也比较接近JS对象。下面这篇文章主要给大家介绍了关于在Mac下安装配置mongodb并创建用户的相关资料,需要的朋友可以参考下
    2018-05-05
  • 在阿里云centos下部署mongodb教程

    在阿里云centos下部署mongodb教程

    这里给大家分享的是作者在阿里云centos下部署mongodb的过程全记录,非常的详细,也遇到了很多问题,最终部署成功,希望对大家能够有所帮助
    2017-08-08
  • Mongodb 如何将时间戳转换为年月日日期

    Mongodb 如何将时间戳转换为年月日日期

    这篇文章主要介绍了Mongodb 如何将时间戳转换为年月日日期,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • MongoDB模糊查询操作案例详解(类关系型数据库的 like 和 not like)

    MongoDB模糊查询操作案例详解(类关系型数据库的 like 和 not like)

    这篇文章主要介绍了MongoDB的模糊查询操作(类关系型数据库的 like 和 not like) ,本文通过代码案例分析给大家介绍的非常详细,具有一定的参考借鉴价值,,需要的朋友可以参考下
    2019-07-07
  • Mongodb中MapReduce实现数据聚合方法详解

    Mongodb中MapReduce实现数据聚合方法详解

    Mongodb是针对大数据量环境下诞生的用于保存大数据量的非关系型数据库,针对大量的数据。接下来通过本文给大家介绍Mongodb中MapReduce实现数据聚合方法详解,感兴趣的朋友一起学习吧
    2016-05-05
  • MongoDB实现备份压缩的方法教程

    MongoDB实现备份压缩的方法教程

    这篇文章主要给大家介绍了关于MongoDB实现备份压缩的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-09-09
  • MongoDB Shell 命令实例总结【进阶篇】

    MongoDB Shell 命令实例总结【进阶篇】

    这篇文章主要介绍了MongoDB Shell 命令,结合实例形式总结分析了MongoDB数据库常用的查询、更新、插入、集合、函数等相关操作技巧与注意事项,需要的朋友可以参考下
    2019-02-02
  • MongoDB4.2.5安装方法操作步骤

    MongoDB4.2.5安装方法操作步骤

    这篇文章主要介绍了MongoDB4.2.5安装方法操作步骤,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12

最新评论

?


http://www.vxiaotou.com