Lua脚本 快速掌握

news2024/11/25 16:35:50

1.Lua脚本概述

Lua是一种轻量级的编程语言,由巴西里约热内卢天主教大学开发。设计初衷是为了嵌入应用程序中,提供灵活的配置和脚本能力。Lua具有简洁的语法和强大的扩展性,使得它在多个领域得到了广泛应用。

Lua的特点包括动态类型、自动内存管理、协程、模块和包支持。它使用表(Table)这一数据结构来实现关联数组、集合等多种功能。Lua的执行速度快,且库体积小。

教程链接:Lua 教程 | 菜鸟教程 (runoob.com)

2.快速入门实操:

(1)创建lua脚本

例如在resource下创建名为unlock.lua的脚本:

if(redis.call('get',KEYS[1]) == ARGV[1]) then
    return redis.call('del',KEYS[1])
end
return 0

说明:

  • if 是Lua的条件判断关键字。
  • redis.call 是Lua脚本中调用Redis命令的方法。在这里,它调用了Redis的 GET 命令。
  • KEYS[1] 是一个特殊变量,代表传递给Lua脚本的键名列表中的第一个键。
  • ARGV[1] 是另一个特殊变量,代表传递给Lua脚本的参数列表中的第一个参数。
  • end 标志着if语句块的结束。
  • 如果if条件不成立(即键值不匹配),则执行这个 return 语句。
  • 返回值 0 表示没有进行任何操作。

(2)编写代码

    private static final String KEY_PREFIX = "lock:";
    private static final String ID_PREFIX = UUID.randomUUID().toString();
 
    // 定义一个静态常量 UNLOCK_SCRIPT,类型为 DefaultRedisScript,预期返回值类型为 Long
    private static final DefaultRedisScript<Long> UNLOCK_SCRIPT;
 
    // 静态初始化块,用于初始化静态常量 UNLOCK_SCRIPT
    static{
        UNLOCK_SCRIPT = new DefaultRedisScript<>();
 
        // 设置 Lua 脚本的路径,这里脚本是从类路径下的资源文件 "unlock.lua" 中加载
        UNLOCK_SCRIPT.setLocation(new ClassPathResource("unlock.lua"));
 
        // 指定脚本执行后的返回值类型为 Long.class
        UNLOCK_SCRIPT.setResultType(Long.class);
    }
 
    @Override
    public boolean tryLock(long timeoutSec) {
 
        String threadId = ID_PREFIX + Thread.currentThread().getId();
 
        Boolean flag  = stringRedisTemplate.opsForValue().setIfAbsent(KEY_PREFIX+name,threadId,timeoutSec, TimeUnit.SECONDS);
 
        return Boolean.TRUE.equals(flag);
    }
 
    @Override
    public void unlock(){
        // 使用 StringRedisTemplate 执行 Lua 脚本 UNLOCK_SCRIPT
        stringRedisTemplate.execute(
                // 传递预定义的 Lua 脚本对象 UNLOCK_SCRIPT
                UNLOCK_SCRIPT,
                // 传递一个包含锁键的列表,这里锁键由前缀和锁的名称组成
                Collections.singletonList(KEY_PREFIX + name),
                // 传递一个参数,该参数是线程 ID 前缀加上当前线程的 ID
                ID_PREFIX + Thread.currentThread().getId());
    }

3.了解Spring Data Redis提供的execute方法

查看源码可以知道execute方法可知

第一个参数:确定返回的类型值和脚本文件的位置

第二个参数:传递给脚本文件key的值,如果没有想传递的key值可以传递为空的Collections.emptyList()。在脚本文件中通过KEYS[序号]获取,例如KEY[1]表示第一个Key的值

之后的参数:传递给脚本文件arg的值,在脚本文件中通过ARGV[序号]获取,例如AVG[1]表示第一个arg的值

 4.更复杂的lua脚本示例代码

这里只写了lua脚本,还需要在使用Spring Data Redis提供的 execute方法才能运行,

-- 优惠卷ID,通过ARGV参数传递,ARGV[1]是第一个参数
local voucherId  = ARGV[1]

-- 用户ID,通过ARGV参数传递,ARGV[2]是第二个参数
local userId = ARGV[2]

-- 订单ID,通过ARGV参数传递,ARGV[3]是第三个参数
local orderId = ARGV[3]

-- 库存Key,拼接字符串构建库存的Redis键名
local stockKey = 'seckill:stock:' .. voucherId

-- 订单Key,拼接字符串构建订单的Redis键名
local orderKey = 'seckill:order:' .. voucherId

-- 脚本业务逻辑开始

-- 检查库存是否充足,使用get命令获取库存数量,如果库存小于等于0则返回1
if(tonumber(redis.call('get',stockKey)) <=0 ) then
    -- 库存不足,返回1,这里1通常表示库存不足的错误码
    return 1
end

-- 判断用户是否已经下过单,使用sismember命令检查订单集合中是否包含该用户ID
-- 如果用户已存在订单集合中,返回2
if(tonumber(redis.call('sismember',orderKey,userId)) == 1 ) then
    -- 用户已下单,返回2,这里2通常表示用户重复下单的错误码
    return 2
end

-- 如果库存充足且用户未下单,则减少库存数量,使用incrby命令对库存进行减一操作
redis.call('incrby',stockKey,-1)

-- 将用户ID添加到订单集合中,记录用户已下单,使用sadd命令添加集合元素
redis.call('sadd',orderKey,userId)

-- 将订单信息发送到消息队列中,使用xadd命令向stream.orders消息队列添加一条消息
-- '*': 表示自动生成消息ID
-- 'userId',userId: 消息字段名为userId,值为脚本传入的userId
-- 'voucherId',voucherId: 消息字段名为voucherId,值为脚本传入的voucherId
-- 'id',orderId: 消息字段名为id,值为脚本传入的orderId
-- 发送消息到队列中 XADD stream.orders * k1 v1 k2 v2
--(下面的key值请参考实体类所定义的,因为这个lua脚本是创建订单信息,所以oderId对应实体的id)
redis.call('xadd','stream.orders','*','userId',userId,'voucherId',voucherId,'id',orderId)

-- 如果脚本执行至此,表示操作成功,返回0
return 0

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2035821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

The Sandbox 游戏制作教程第 4 章|使用装备制作游戏,触发独特互动

欢迎回到我们的系列&#xff0c;我们将记录 The Sandbox Game Maker 的 “On-Equip”&#xff08;装备&#xff09;功能的多种用途。 如果你刚加入 The Sandbox&#xff0c;On-Equip 功能是 “可收集组件”&#xff08;Collectable Component&#xff09;中的一个多功能工具&a…

C++ list【常用接口、模拟实现等】

1. list的介绍及使用 1.1 list的介绍 1.list是可以在常数范围内在任意位置进行插入和删除的序列式容器&#xff0c;并且该容器可以前后双向迭代。 2.list的底层是双向链表结构&#xff0c;双向链表中每个元素存储在互不相关的独立节点中&#xff0c;在节点中通过指针指向其前…

MyBatisPlus 第二天

常用注解 1 TableName:数据库表名和实体类名不同时,会出现以下报错 在实体类上添加 TableName("t_user") 在开发的过程中&#xff0c;我们经常遇到以上的问题&#xff0c;即实体类所对应的表都有固定的前缀&#xff0c;例如t_或tbl_此时&#xff0c;可以使用MyBa…

el-tree自定义节点内容

<el-tree :data"data" :props"defaultProps" ref"treeRef" show-checkbox check-change"handleCheckChange"><!-- 自定义节点内容 --><template #default"{ node, data, store }"><span class"tr…

无人值守人工智能智慧系统数据分析:深度洞察与未来展望

无人值守人工智能智慧系统数据分析&#xff1a;深度洞察与未来展望 随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术已逐渐渗透到社会经济的各个领域&#xff0c;其中无人值守人工智能智慧系统作为AI技术应用的前沿阵地&#xff0c;正引领着一场深刻的…

【数量关系】毛娃儿笔记

一、导学 1、比例的常见作用 &#xff08;1&#xff09;通过份数求数量 甲&#xff1a;乙1:2 那么甲乙的人数总和一定是3的倍数 &#xff08;2&#xff09;得到倍数关系 不同的说法都可以转化为比例&#xff0c;比如甲是乙的两倍2:1、甲是乙的4/34:3、甲比乙多25%5:4 &am…

基于vue框架的4S店汽车维修保养管理系统28a7y(程序+源码+数据库+调试部署+开发环境)系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;客户,技师,车辆信息,财务,客户维修,维修分配,维修订单,保养预约,保养分配,保养订单,维修费用,保养费用 开题报告内容 基于Vue框架的4S店汽车维修保养管理系统 开题报告 一、项目背景与意义 随着汽车产业的迅猛发展&#xff0c;4S店作…

【微前端中常见的问题及其解决办法】

随着前端技术的飞速发展&#xff0c;大型应用系统的复杂性和规模性日益增加&#xff0c;传统的单体前端架构逐渐暴露出维护成本高、升级困难、技术栈单一等问题。为了应对这些挑战&#xff0c;微前端&#xff08;Micro-Frontends&#xff09;作为一种新的架构模式应运而生。微前…

自研Vue3低代码海报制作平台第一步:基础拖拽组件开发

学习来源&#xff1a;稀土掘金 - 幽月之格大佬的技术专栏可拖拽、缩放、旋转组件 - 著作&#xff1a;可拖拽、缩放、旋转组件实现细节 非常感谢大佬&#xff01;受益匪浅&#xff01; 前面我们学习了很多vue3的知识&#xff0c;是时候把它们用起来做一个有意思的平台&#xf…

合合信息OCR支持30类国内常见票据一站式分类识别,支持医疗发票、数电票识别

合合信息TextIn平台明星产品——国内通用票据识别&#xff0c;重磅更新&#xff01; 产品支持票据类型扩展到23大类、30小类&#xff0c;覆盖场景更全面&#xff0c;同时升级优化了多款票据识别模型&#xff0c;平均识别率较前版本提升11.5%&#xff0c;整体识别速度提升21.9%…

关于k8s的Pod控制器

目录 1.Pod控制器及其作用 2.pod控制器类型 2.1 ReplicaSet: 2.2 Deployment 2.3 DaemonSet 2.4 StatefulSet 2.5 Job 2.6 Cronjob 3.Pod与控制器之间的关系 3.1 Deployment 3.2 SatefulSet 3.3 DaemonSet 3.4 job 3.5 cronjob 1.Pod控制器及其作用 Pod控制器&am…

北京某银行成功替换F5!更多实施细节曝光→

随着国家对金融行业技术创新的持续关注&#xff0c;金融行业的诸多用户正积极开展业务系统的数字化创新。 在这一领域&#xff0c;保障业务稳定性和连续性始终是最重要的议题。今天&#xff0c;为大家介绍的最佳实践来自北京某银行&#xff0c;他们通过积极探索和评估&#xf…

Python酷库之旅-第三方库Pandas(078)

目录 一、用法精讲 321、pandas.Series.str.len方法 321-1、语法 321-2、参数 321-3、功能 321-4、返回值 321-5、说明 321-6、用法 321-6-1、数据准备 321-6-2、代码示例 321-6-3、结果输出 322、pandas.Series.str.ljust方法 322-1、语法 322-2、参数 322-3、…

HMAC算法:构建安全认证的基石

在信息安全领域&#xff0c;数据完整性和认证是至关重要的。HMAC&#xff08;Hash-based Message Authentication Code&#xff09;算法作为一种基于哈希的消息认证码&#xff0c;广泛应用于数据传输过程中的安全认证。本文将带你了解HMAC算法的原理、特点及其应用场景。 HMAC算…

全方位解析RAG技术:从概念理论到代码实操,一文助你掌握检索增强生成的精髓!

一、LLMs 已经具备了较强能力了&#xff0c;为什么还需要 RAG(检索增强生成)? 尽管 LLM 已展现出显著的能力&#xff0c;但以下几个挑战依然值得关注&#xff1a; 幻觉问题&#xff1a;LLM 采用基于统计的概率方法逐词生成文本&#xff0c;这一机制内在地导致其可能出现看似…

Git基础使用教程

版本控制手册 本文中出现的 [ ] 为根据需求自行修改的变量。 基本命令 git init&#xff1a;将当前目录配置成git仓库&#xff0c;信息记录在隐藏的.git文件夹中。 git config --global user.name [xxx]&#xff1a;设置全局用户名&#xff0c;信息记录在~/.gitconfig文件中。…

厦门商家微信小程序、抖音、支付宝小程序同步上线

想要迅速在厦门开设微信小程序店铺&#xff1f;乔拓云网站提供了简便快捷的解决方案。只需四步&#xff0c;轻松复制模板&#xff0c;定制内容&#xff0c;即可上线专属小程序。 首先&#xff0c;访问乔拓云官网&#xff0c;完成免费注册&#xff0c;轻松获得您的专属账号。不论…

winform程序集的名称

1.更改程序集名称后 AssemblyInfo.cs中也要手动更改 2.鼠标放在程序集上右键&#xff0c;点击最后一栏 “属性” 3.更改Settings.Designer.cs中的名称 4.可能还有别的地方需要改&#xff0c;可以搜索旧名称来找到需要更改的地方进行更新。 PS: 当更改程序集名称时&#xff0c;…

图算法系列1: 图算法的分类有哪些?(上)

大约在公元9世纪上半叶&#xff0c;来自中亚古国花剌子模的波斯数学家花剌子米(al-Khwarizmi)先后出版了两本对数学界有深远影响的书籍《印度数字算术》与《代数学》​&#xff0c;前者在12世纪被翻译为拉丁文传入欧洲&#xff0c;十进制也因此传入欧洲&#xff0c;最终所形成的…

DLL文件损坏怎么办?10种DLL修复方法帮你搞定

在日常使用Windows电脑时&#xff0c;我们常常遇到应用程序无法打开、系统崩溃甚至蓝屏的问题&#xff0c;背后原因往往是DLL文件的损坏或丢失。DLL文件是系统和软件运行的关键部分&#xff0c;一旦出现问题&#xff0c;会严重影响我们的日常操作。为了避免这些困扰&#xff0c…