您好,欢迎来到伴沃教育。
搜索
您的当前位置:首页java中利用Redis整合Lua脚本

java中利用Redis整合Lua脚本

来源:伴沃教育


1.什么是Lua脚本

Lua 编程语言编写的脚本程序。Lua 是一种轻量级的脚本语言,由巴西里约热内卢天主教大学的 Luiz Henrique de Figueiredo 教授及其团队于 1993 年创建。它被设计为一种简单、快速、可嵌入的编程语言,广泛用于嵌入式系统、游戏开发、网络编程等领域。

Lua脚本特性:

        轻量级:Lua 的体积小,易于集成到其他应用程序中。

        高性能:Lua 是一种编译型语言,执行效率高。

        可扩展性:Lua 提供了丰富的 API,允许开发者扩展其功能。

        跨平台:Lua 可以在多种操作系统上运行,包括 Windows、Linux、macOS 等。

详情:

2.使用Lua脚本

Redis提供了Lua脚本功能,在一个脚本中辨析多条Redis命令,确保多条命令执行时的原子性。

// 执行redis命令
redis.call('命令名称', 'key','其他参数',...)

如果要进行set操作,例如set一个name为dahei,执行脚本如下: 

redis.call('set', 'name', 'dahei')

 如果先执行set操作,再获取set的key,脚本如下:

// 先set
redis.call('set', 'name', 'dahei')

// 再获取get
loacl name = redis.call('get', 'name')

// 返回
return name

 3.Redis使用Lua脚本

以下是Redis调用Lua脚本的整个命令

其中    "return redis.call('set', 'name', 'dahei')"   是脚本的内容

最后面那个0是脚本需要的key类型的参数个数 

如果脚本中的key,value不想写死,可以作为参数传递。key类型的参数会放入KYES数组。其他参数会放入ARGV数组,在脚本中可以从KEYS和ARGV数组获取这些参数

 其中    "return redis.call('set', 'name', 'dahei')"   依然是脚本的内容

最后面那个1是脚本需要的key类型的参数个数 

name对应的就是KEYS[1]

dahei对应的是ARGV[1]

在Lua语言中数组的下标是从1开始的

 4.在java中利用Redis整合Lua脚本

 创建Lua脚本如下:

 在Lua脚本中编写逻辑代码如下:

具体的Lua语言学习见第一点最后的详情

这里将Lua脚本运用在Redis分布式锁中

利用RedisTemplae调用Lua脚本的API如下:

 调用Lua脚本如下:

这里将executeAPI所需要的参数提前准备好,因为RedisTemplate是一个接口,所以用它的实现类DefaultRedisScrpt<T>来实例化对象,来对Lua脚本进行加载,定义了一个静态代码块来设置Lua脚本的位置,返回值

最后在unlock()方法中执行Lua脚本

 // 执行Lua脚本需要用到RedisScript进行加载,提前定义好
    private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;
    static{
        UNLOCK_SCRIPT = new DefaultRedisScript<>();
        // 指定脚本 -- 使用ClassPathResource 就会自动在classpath路径下去找
        UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua"));
        // 设置返回值
        UNLOCK_SCRIPT.setResultType(Long.class);
    }
    private final String name;
    private final StringRedisTemplate stringRedisTemplate;

    public SimpleRedisLock(StringRedisTemplate stringRedisTemplate, String name) {
        this.name = name;
        this.stringRedisTemplate = stringRedisTemplate;
    }
    @Override
    public boolean tryLock(long timeoutSec) {
        // 获取线程标识
        String threadId = ID_PREFIX + Thread.currentThread().getId();
        // 获取锁
        Boolean success = stringRedisTemplate.opsForValue().setIfAbsent(KEY_PREFIX + name, threadId, timeoutSec, TimeUnit.SECONDS);
       // return BooleanUtil.isTrue(success);
        return Boolean.TRUE.equals(success);
    }
    @Override
    public void unlock() {
        // 基于Lua脚本实现 -- 调用Lua脚本,execute
        // Collections.singletonList() -- 收集成单元素集合
        stringRedisTemplate.execute(UNLOCK_SCRIPT,
                Collections.singletonList(KEY_PREFIX + name),
                ID_PREFIX + Thread.currentThread().getId()
                );
    }

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- bangwoyixia.com 版权所有 湘ICP备2023022004号-2

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务