java 从零实现属于你的 redis 分布式锁( 三 )

jedis 实现我们实现一个 jedis 单点版本的:
package com.github.houbb.lock.redis.support.operator.impl;import com.github.houbb.lock.redis.constant.LockRedisConst;import com.github.houbb.lock.redis.support.operator.IOperator;import redis.clients.jedis.Jedis;import java.util.Collections;/** * Redis 客户端 * @author binbin.hou * @since 0.0.1 */public class JedisOperator implements IOperator {/*** jedis 客户端* @since 0.0.1*/private final Jedis jedis;public JedisOperator(Jedis jedis) {this.jedis = jedis;}/*** 尝试获取分布式锁** expireTimeMills 保证当前进程挂掉 , 也能释放锁** requestId 保证解锁的是当前进程(锁的持有者)** @param lockKey锁* @param requestId请求标识* @param expireTimeMills 超期时间* @return 是否获取成功* @since 0.0.1*/@Overridepublic boolean lock(String lockKey, String requestId, int expireTimeMills) {String result = jedis.set(lockKey, requestId, LockRedisConst.SET_IF_NOT_EXIST, LockRedisConst.SET_WITH_EXPIRE_TIME, expireTimeMills);return LockRedisConst.LOCK_SUCCESS.equals(result);}/*** 解锁** (1)使用 requestId , 保证为当前锁的持有者* (2)使用 lua 脚本 , 保证执行的原子性 。** @param lockKey锁 key* @param requestId 请求标识* @return 结果* @since 0.0.1*/@Overridepublic boolean unlock(String lockKey, String requestId) {String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));return LockRedisConst.RELEASE_SUCCESS.equals(result);}}这里时最核心的部分 。
别看简单几行代码 , 需要注意的点还是很多的 。
加锁加锁时附带 requestId , 用来标识自己为锁的持有者 。
SETNX 当 key 不存在时才进行加锁 。
设置加锁的过期时间 , 避免因异常等原因未释放锁 , 导致锁的长时间占用 。
解锁使用 lua 脚本 , 保证操作的原子性 。
为了证明为锁的持有者 , 传入 requestId 。
测试验证maven 引入com.github.houbblock-core0.0.1测试代码Jedis jedis = new Jedis("127.0.0.1", 6379);IOperator operator = new JedisOperator(jedis);// 获取锁ILock lock = LockRedisBs.newInstance().operator(operator).lock();try {boolean lockResult = lock.tryLock();System.out.println(lockResult);// 业务处理} catch (Exception e) {e.printStackTrace();} finally {lock.unlock();}小结到这里 , 一个简单版本的 redis 分布式锁就实现完成了 。
当然还有很多可以改进的地方:
(1)比如引入递增的 sequence , 避免分布式锁中的 GC 导致的问题
(2)对于更多 redis 服务端+客户端的支持
(3)对于注解式 redis 分布式锁的支持
希望对你有帮助 , 感兴趣的可以关注一下 , 便于实时接收最新内容 。
觉得本文对你有帮助的话 , 欢迎点赞评论收藏转发一波 。
各位极客的点赞转发收藏 , 是我创作的最大动力~
不知道你有哪些收获呢?或者有其他更多的想法 , 欢迎留言区和我一起讨论 , 期待与你的思考相遇 。
文中如果链接失效 , 可以点击 {阅读原文} 。
java 从零实现属于你的 redis 分布式锁文章插图