java中利用Redis整合Lua脚本

目录

1.什么是Lua脚本

2.使用Lua脚本

 3.Redis使用Lua脚本

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


1.什么是Lua脚本

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

Lua脚本特性:

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

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

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

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

详情:Lua脚本详细学习

2.使用Lua脚本

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

redis提供的调用函数,语法如下:

以下都是Lua脚本

// 执行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()
                );
    }

  • 15
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值