Redis Lua同步锁实现源码解析

 更新时间:2023年05月18日 10:43:23   作者:多喝灬丶烫水  
这篇文章主要为大家介绍了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同步锁的资料请关注脚本之家其它相关文章!

相关文章

  • 聊聊使用RedisTemplat实现简单的分布式锁的问题

    聊聊使用RedisTemplat实现简单的分布式锁的问题

    这篇文章主要介绍了使用RedisTemplat实现简单的分布式锁问题,文中给大家介绍在SpringBootTest中编写测试模块的详细代码,需要的朋友可以参考下
    2021-11-11
  • redis实现多级缓存同步方案详解

    redis实现多级缓存同步方案详解

    这篇文章主要介绍了redis实现多级缓存同步方案详解,本文通过示例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-12-12
  • 关于SpringBoot 使用 Redis 分布式锁解决并发问题

    关于SpringBoot 使用 Redis 分布式锁解决并发问题

    针对上面问题,一般的解决方案是使用分布式锁来解决,本文通过场景分析给大家介绍关于SpringBoot 使用 Redis 分布式锁解决并发问题,感兴趣的朋友一起看看吧
    2021-11-11
  • 使用Redis实现分布式锁的方法

    使用Redis实现分布式锁的方法

    为了保证我们线上服务的并发性和安全性,目前我们的服务一般抛弃了单体应用,采用的都是扩展性很强的分布式架构,这篇文章主要介绍了使用Redis实现分布式锁的方法,需要的朋友可以参考下
    2022-06-06
  • Redis Sorted Set 跳表的实现示例

    Redis Sorted Set 跳表的实现示例

    本文详细解析了Redis中SortedSet跳表的实现原理,阐述了跳表的基本概念、结构及其在SortedSet中的应用,同时也指出了跳表在实际使用中的优势和局限,可以更好地运用Redis的SortedSet,优化高并发环境中的数据查询与操作,感兴趣的可以了解一下
    2024-10-10
  • Redis 如何清空所有数据

    Redis 如何清空所有数据

    这篇文章主要介绍了Redis 如何清空所有数据,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-08-08
  • Redis的五种基本类型和业务场景和使用方式

    Redis的五种基本类型和业务场景和使用方式

    Redis是一种高性能的键值存储数据库,支持多种数据结构如字符串、列表、集合、哈希表和有序集合等,它提供丰富的API和持久化功能,适用于缓存、消息队列、排行榜等多种场景,Redis能够实现高速读写操作,尤其适合需要快速响应的应用
    2024-10-10
  • 关于linux redis安装及安装遇到的问题

    关于linux redis安装及安装遇到的问题

    这篇文章主要介绍了关于linux redis安装及安装遇到的问题,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • 在Redis数据库中实现分布式速率限制的方法

    在Redis数据库中实现分布式速率限制的方法

    这篇文章主要介绍了在Redis数据库中实现分布式速率限制的方法,文中展示了一个用Python编写的应用示例,需要的朋友可以参考下
    2015-06-06
  • Redis缓存IO模型的演进教程示例精讲

    Redis缓存IO模型的演进教程示例精讲

    这篇文章主要为大家介绍了Redis线程IO模型演进的教程示例精讲,有需要朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪
    2021-11-11

最新评论