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


今天主机评测网小编给大家分享一下基于Mongodb分布式锁怎么解决定时任务并发执行问题的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。

前言

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

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

All in one Code

先上代码

ponent@Slf4jpublicclassMongoDBLock{privatestaticfinalintDEFAULT_LOCK_TIMEOUT=30;//锁的默认超时时间,单位秒privateMongoTemplatemongoTemplate;privateintlockTimeout;publicMongoDBLock(MongoTemplatemongoTemplate){this.mongoTemplate=mongoTemplate;this.lockTimeout=DEFAULT_LOCK_TIMEOUT;}/***尝试获取分布式锁**@paramlockKey锁的key*@returntrue:获取锁成功,false:获取锁失败*/privatebooleanacquireLock(StringlockKey){LockDocumentdocument=newLockDocument();document.setId(lockKey);document.setExpireAt(Instant.ofEpochMilli(Instant.now().toEpochMilli()+lockTimeout*1000));try{mongoTemplate.insert(document);returntrue;}catch(Exceptione){}returnfalse;}/***释放分布式锁**@paramlockKey锁的key*/privatevoidreleaseLock(StringlockKey){Queryquery=newQuery(Criteria.where("key").is(lockKey));mongoTemplate.remove(query,LockDocument.class);log.info("程序执行成功,释放分布式锁,lockKey:{}",lockKey);}/***分布式锁入口方法,参数lockName为锁的名称,lockKey为需要加锁的key,执行完成后自动释放锁**@paramlockKey*@paramtask*@param<T>*@throwsException*/public<T>voidexecuteWithLock(StringlockKey,ITask<T>task)throwsException{booleanlocked=acquireLock(lockKey);if(locked){log.info("获取分布式锁成功,lockKey:{}",lockKey);try{task.execute();}finally{releaseLock(lockKey);}}else{log.warn("获取分布式锁失败,lockKey:{}",lockKey);thrownewAppException("获取分布式锁失败!");}}@Data@Document(collection="lock_collection")staticclassLockDocument{@IdprivateStringid;@Indexed(expireAfterSeconds=DEFAULT_LOCK_TIMEOUT)privateInstantexpireAt;}@FunctionalInterfacepublicinterfaceITask<T>{Texecute()throwsException;}}

调用示例

@ResourceMongoDBLockmongoDBLock;mongoDBLock.executeWithLock("key",()->{//dosomethingreturnnull;});

原理

  • 使用key作为主键,利用mongodb的insert原子性保障LockDocument不会重复插入

  • LockDocument中expireAt字段利用的mongodb索引过期机制,解决死锁问题,这里设置超时时间是30秒,并在执行完成之后会主动释放锁

以上就是“基于Mongodb分布式锁怎么解决定时任务并发执行问题”这篇文章的所有内容,感谢各位的阅读!相信大家阅读完这篇文章都有很大的收获,小编每天都会为大家更新不同的知识,如果还想学习更多的知识,请关注主机评测网行业资讯频道。


上一篇:微服务之注册中心和配置中心Consul怎么使用

下一篇:C++怎么获取当前正在运行函数的名称


Copyright © 2002-2019 测速网 https://www.inhv.cn/ 皖ICP备2023010105号 城市 地区 街道
温馨提示:部分文章图片数据来源与网络,仅供参考!版权归原作者所有,如有侵权请联系删除!
热门搜索