基于Redis封装分布式锁

基于Redis的分布式锁封装记录

  • 首先搭建一个基于Redis Server端(略过)
  • Redis客户端连接池工具类(RedisPool.java)的封装
    • 利用类的static块初始化连接池
    • 初始化的参数包含最大连接数、最大空闲连接数、最小空闲连接数等基本参数


      image.png
  • 初始化连接池时读取mvc.default.properties配置文件中的jedis-pool配置,该配置值格式为:host,port连接到redis中,后续项目中可配置此自定义
  • 封装的加锁操作分为非阻塞锁和阻塞锁,阻塞锁下封装了自定义失效时间锁和默认失效时间(10s)锁
Jedis jedis = RedisPool.getJedis();
String result = jedis.set(key, request, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
RedisPool.close(jedis);
  • 阻塞锁的实现基于for(;;)循环,防止Cpu一直消耗,在循环体内加入Thread.sleep()保证时间片切换
for (;;) {
  Jedis jedis = RedisPool.getJedis();
  String result = jedis.set(key, request, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, 10 * TIME);
  RedisPool.close(jedis);
  if (LOCK_SUCCESS.equals(result)) {
    break;
  }
  // 防止一直消耗 CPU
  Thread.sleep(100);
}
  • 释放锁时需要调用Lua脚本来完成,传统的释放锁会涉及get到资源,然后del掉,使用Java client语法操作两个步骤不能保障原子性,所以在此采用Lua脚本来保证get和del为原子操作
public static boolean unlock(String key, String request) {
  String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
  Jedis jedis = RedisPool.getJedis();
  Object result = jedis.eval(script, Collections.singletonList(key), Collections.singletonList(request));
  RedisPool.close(jedis);
  if (RELEASE_SUCCESS.equals(result)) {
    return true;
  }
  return false;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 本文将从Redis的基本特性入手,通过讲述Redis的数据结构和主要命令对Redis的基本能力进行直观介绍。之后概...
    kelgon阅读 61,255评论 23 625
  • 老酒新茶,要与你共饮,大城小事,要说给你听,夜阑卧听风吹雨,铁马是你,冰河也是你,你手指的方向,就是我的战场,我是...
    冷江枫阅读 278评论 0 0
  • 所以说,当一种族学会抵御所有限制,把环境制造得适宜自己种族生长。种群无限制繁衍,在上帝眼中,这个种族有必要毁灭。
    浮木生阅读 148评论 0 0
  • 上一章:【职人】15 孩子争夺战 那时,不光是庭下的我们这些大老粗,就连庭上的女法官也是听得焦头烂额。就在双方对峙...
    铁慕真阅读 870评论 1 32