控制定时任务的执行

如果程序是部署在很多台服务器上,当定时任务执行的时候,会导致多个定时任务执行
1.执行插入数据,导致数据插入多次,脏数据问题
如何解决
1.将定时任务从主程序中拆分出来

导致的问题:如果有多个定时任务,会很麻烦
2.写死配置,每个服务器都有运行定时任务,但在运行的时候判断,如果ip为指定的服务器才执行,其他的执行返回,成本低。
导致的问题:ip可能不固定,如果要修改ip会很麻烦
3.动态配置:代码无需重启,将配置写在可以更新的地方
- 数据库
- redis
- 配置中心
问题:服务器多了,ip不可控,还是要人工修改
4.分布式锁
只有抢到锁的服务器才能执行定时任务,坏处:增加了成本。好处:不用手动配置

锁:控制共享资源在同一时间只能被某些线程(用户/服务器)所访问
Java实现锁:synchronized关键字、并发包的类
问题:只对单个jvm有效
分布式锁
为什么需要分布式锁?
1.控制共享资源在同一时间只能被某些线程(用户/服务器)所访问
2.单个锁只对单个jvm有效
分布式锁实现的关键
抢锁机制
怎么保证同一时间只有一个服务器能抢到锁?
核心思想就是:先来的人先设置一个标识表示已经有线程访问,其他线程不能访问了,继续等待。等来的人执行完,把标识清空,其他的人继续抢锁。
实现
1.Mysql数据库 select for update 行级锁(最简单)
2.乐观锁
✔3.redis存标识:内存数据库,速度快。支持set key value nx(意思是set if not exist)
4.zookeeper实现
使用redis实现注意事项
1.执行完一定要释放锁
2.一定要给锁设置过期时间
3.如果方法执行过长,而锁已经过期了。(解决方法:续期,抢到锁的线程可以延长锁的时间)
- 这样还是会导致多个方法同时执行
- 释放掉别人的锁(解决方法:在释放前判断是否是自己的锁)

浙公网安备 33010602011771号