写在前面
最近在开发活动,活动最头痛的就是高并发的问题,再加上现在都是分布式,java自带的锁就没有用武之地了。分布式锁就油然而生,网上的教程也是一大堆。我主要记录一下自己暂时是怎么解决的。
Redis实现分布式锁
Redis我就不详细介绍了,之所以被广泛使用的一个原因:单线程速度却异常的快。
springboot的StringRedisTemplate
之前项目一直用的spring-boot-starter-data-redis 包的redis客户端。挺好用的封装的方法也很齐全,分布式锁的实现主要靠setIfAbsent
也就是redis 原生命令的SETNX,大致就是key存在就返回false,不存在就set成功返回true。更专业一点:setkey就相当于尝试获取一把锁,false获取锁失败,别的线程在占有锁,true获取到锁。
问题
早期的客户端版本可能存在问题,可以看到setIfAbsent没有过期时间的配置,
一旦线程获取到锁的时候程序异常,或者重新发版没有释放锁,那么这里就会死锁。我用的1.8.13版本的就是这样的,获取锁和定时释放锁不是原子操作,导致很容易出现死锁,还不易排查,稍新的版本已经支持原子操作。