文章目录
- 分布式锁
- 1、什么是分布式锁:
- 2、分布式锁应该具备哪些条件:
- 基于数据库的分布式锁
- 代码传送
- 代码运行
分布式锁
1、什么是分布式锁:
分布式锁,即分布式系统中的锁。在单体应用中我们通过锁解决的是控制共享资源访问的问题,而分布式锁,就是解决了分布式系统中控制共享资源访问的问题。与单体应用不同的是,分布式系统中竞争共享资源的最小粒度从线程升级成了进程。
2、分布式锁应该具备哪些条件:
在分布式系统环境下,一个方法在同一时间只能被一个机器的一个线程执行
高可用的获取锁与释放锁
高性能的获取锁与释放锁
具备可重入特性(可理解为重新进入,由多于一个任务并发使用,而不必担心数据错误)
具备锁失效机制,即自动解锁,防止死锁
具备非阻塞锁特性,即没有获取到锁将直接返回获取锁失败
基于数据库的分布式锁
核心代码
@Slf4j
@Component
public class ScheduleJob
{private String key = "job001";@AutowiredJdbcTemplate jdbcTemplate;String ip;/*** 初始化*/@PostConstructpublic void init(){long count = jdbcTemplate.queryForObject("SELECT count(*) FROM t_schedule_lock WHERE key_name=?", Long.class, key);if (count == 0){jdbcTemplate.update("INSERT INTO t_schedule_lock(key_name, time) VALUES(?, now())", key);}try{ip = InetAddress.getLocalHost().getHostAddress();}catch (UnknownHostException e){}}@Scheduled(cron = "0/10 * * * * ?")public void run(){try{if (getLock(9L)){log.info("[{}] #### hello world ***********", ip);}else{log.info("[{}] 没抢到,骂骂咧咧的走了......", ip);}}catch (Exception e){log.error(e.getMessage(), e);}}/*** 获取lock,并更新time为下次执行时间 now()+ seconds<BR>* * 注意: 为了保证jdbcTemplate.update执行成功,一般设置seconds稍小于@Scheduled设置的运行间隔秒数* * @return*/private boolean getLock(long seconds){return jdbcTemplate.update("UPDATE t_schedule_lock SET time = adddate(now(), INTERVAL ? SECOND) WHERE key_name = ? AND now() > time", seconds, key) > 0;}
}
代码传送
https://gitee.com/00fly/effict-side/tree/master/springboot-schedule
项目已经实现了maven插件打包镜像,上传阿里云镜像仓库。
代码运行
下载docker文件下的这2个文件,上传至带有docker-compose以及docker环境的服务器
运行命令
sh scale.shdocker psdocker logs -f <containerId>
运行效果图:
有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!
-over-