Redis Lua同步锁实现源码解析
作者:多喝灬丶烫水
这篇文章主要为大家介绍了Redis Lua同步锁实现源码解析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
Redis+Lua同步锁
Jedis配置
@Configuration @Getter @Setter @Slf4j @ConfigurationProperties(prefix = "jedis") public class JedisConfig { @Value("${spring.redis.host}") private String host; @Value("${spring.redis.port}") private int port; @Value("${spring.redis.password}") private String password; private int timeout; private int maxTotal; private int maxIdle; private int minIdle; @Bean public JedisPool jedisPool() { JedisPoolConfig jedisPoolConfig = new JedisPoolConfig(); jedisPoolConfig.setMaxIdle(maxIdle); jedisPoolConfig.setMinIdle(minIdle); jedisPoolConfig.setMaxTotal(maxTotal); JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password); log.info("JedisPool连接成功:" + host + "\t" + port); return jedisPool; } }
Jedis工具类→获取jedis
@Component public class JedisUtil { @Resource private JedisPool jedisPool; /** * 获取Jedis资源 */ public Jedis getJedis() { return jedisPool.getResource(); } /** * 释放Jedis连接 */ public void close(Jedis jedis) { if (jedis != null) { jedis.close(); } } }
redis 锁工具类
public class RedisLockUtil { private static final Long RELEASE_SUCCESS = 1L; private static final String PREFIX = "API_LOCK_"; /** * 释放分布式锁 * * @param jedis * @param lockKey * @param valve * @return boolean * @author ll * @date 2023/02/09 14:31 */ public static boolean unLock(Jedis jedis, String lockKey, String valve) { 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(PREFIX + lockKey), Collections.singletonList(PREFIX + valve)); if (RELEASE_SUCCESS.equals(result)) { return true; } return false; } /** * 加分布式锁 * * @param jedis * @param lockKey * @param valve * @param timeout * @return boolean * @author ll * @date 2023/02/09 14:31 */ public static boolean lock(Jedis jedis, String lockKey, String valve, int timeout) { String script = "if redis.call('setnx',KEYS[1],ARGV[1]) == 1 then" + " redis.call('expire',KEYS[1],ARGV[2]) return 1 else return 0 end"; Object result = jedis.eval(script, Collections.singletonList(PREFIX + lockKey), Lists.newArrayList(PREFIX + valve, String.valueOf(timeout))); //判断是否成功 if (RELEASE_SUCCESS.equals(result)) { return true; } return false; } }
加锁示例(jedis+lua)
@Slf4j @Component public class InterfaceEventListener { @Resource private JedisUtil jedisUtil; @Value("${jedis.lock.cycle-number}") private int cycleNumber; @Value("${jedis.lock.expire-time}") private int expireTime; @Value("${jedis.lock.sleep-time}") private int sleepTime; @Value("${spring.redis.database}") private int database; public void onApplicationEvent(InterfaceEvent event) { Jedis jedis = jedisUtil.getJedis(); jedis.select(database); boolean unLock = false; boolean lock; int currentNumber = 0; try { do { lock = RedisLockUtil.lock(jedis, "lockKey", "valve", expireTime); if (lock) { try { //todo 加锁的代码 } catch (Exception e) { log.error(e.getMessage()); e.printStackTrace(); } finally { unLock = RedisLockUtil.unLock(jedis, detectCode, detectCode); } } currentNumber++; Thread.sleep(sleepTime); } while (!unLock && currentNumber < cycleNumber); } catch (Exception e) { e.printStackTrace(); log.error(e.getMessage()); } finally { jedisUtil.close(jedis); } } }
以上就是Redis Lua同步锁实现源码解析的详细内容,更多关于Redis Lua同步锁的资料请关注脚本之家其它相关文章!