Java 생태계/Redis에서 Lua 스크립트를 사용하는 방법
1. LUA 설치
Mac에 LUA를 설치하는 것은 매우 간단합니다. brew
관련 명령을 사용하면 됩니다. brew
相关命令;
brew install lua
使用lua -v
命令可以看到lua已经安装完毕。
1)简单使用
创建一个test.lua文件,内容为:
执行命令:
lua test.lua
输出为:
二、lua语法简介
Lua 提供了交互式编程和脚本式编程:
交互式编程:直接在命令行中输入语法,可以立即执行并查看到执行效果。
脚本是编程:编写脚本文件,然后再执行。
1、注释
lua提供两种注释方式:单行注释和多行注释
1)单行注释
使用两个减号;
--
2)多行注释
--[[ 多行注释 多行注释 --]]
2、关键字
下列为 Lua 的保留关键字,和Java一样 保留关键字不能作为常量或变量。
3、变量
默认的情况下,定义一个变量都是全局变量;如果要用局部变量 需要声明为local
;
1)全局变量
全局变量不需要声明,给一个变量赋值后便创建了这个全局变量;
访问一个没有初始化的全局变量也不会出错,只不过会得到结果:nil
只要将变量赋值为nil,就可以删除全局变量;换句话说,当且仅当变量为nil时,该变量不存在。
此外,一般以下划线开头连接一串大写字母的名字(比如 _VERSION)被保留用于 Lua 内部全局变量。
2)局部变量
-- 局部变量赋值 local b=2
4、数据类型
Lua 是一个动态类型语言,变量不要类型定义,只需要为变量赋值。 值可以存储在变量中,作为参数传递或结果返回。
Lua 中有 8 个基本类型分别为:nil、boolean、number、string、userdata、function、thread 和 table。
1)Lua数组
在Lua 数组中,索引值是从 1 开始,可以指定为从 0 开始。
2)字符串操作
..
连接两个字符串;string.sub()
用于截取字符串;
string.sub(s, i [, j])
s:要截取的字符串;
i:截取开始位置;
j:截取结束位置,默认为 -1,最后一个字符;
string.find()
用于字符串查找
string.find (str, substr, [init, [plain]])
在一个指定的目标字符串 str 中搜索指定的内容 substr,如果找到了一个匹配的子串,就会返回这个子串的起始索引和结束索引,不存在则返回 nil。
init
指定了搜索的起始位置,默认为 1,可以一个负数,表示从后往前数的字符个数。plain
表示是否使用简单模式,默认为 false,true 只做简单的查找子串的操作,false 表示使用正则模式匹配。
5、if-else
条件表达式结果可以是任何值,Lua认为false和nil为假,true和非nil为真。
整体的if-else结构和我们使用的高级语言(Java、GO)类似,区别在于:LUA中的if()表达式满足之后想要做一些其余逻辑,需要紧跟then
,并且流程控制以end
if(xxx) then print("xxx") else if(xx) then print("xx") else print("x") end

lua -v
명령을 사용하여 lua가 변경되었는지 확인하세요. 설치되었습니다. 1) 간단히 를 사용하여 다음 내용이 포함된 test.lua 파일을 만듭니다. 
실행 명령:
for var=exp1,exp2,exp3 do <执行体> end
출력은 다음과 같습니다:

--< /code>🎜🎜2) 여러 줄 주석🎜<div class="code" style="position:relative; padding:0px; margin:0px;"><div class="code" style="position:relative; padding:0px; margin:0px;"><pre class='brush:php;toolbar:false;'>--打印数组a的所有值
a = {"one", "two", "three"}
for i, v in ipairs(a) do
print(i, v)
end</pre><div class="contentsignin">로그인 후 복사</div></div><div class="contentsignin">로그인 후 복사</div></div>🎜2. 키워드🎜🎜다음은 Lua의 예약어입니다. 예약어는 Java와 마찬가지로 상수나 변수로 사용할 수 없습니다. 🎜🎜<img src="/static/imghw/default1.png" data-src="https://img.php.cn/upload/article/000/887/227/168571687129252.png" class="lazy" alt="Java 생태학/Redis에서 Lua 스크립트를 사용하는 방법" />🎜🎜3 . 변수 🎜🎜기본적으로 변수 정의는 전역 변수이며, 지역 변수를 사용하려면 <code>local
로 선언해야 합니다. 🎜🎜1) 전역 변수는 🎜🎜전역 변수입니다. 선언할 필요는 없으며 변수를 제공합니다. 이 전역 변수는 할당 후에 생성됩니다. 🎜🎜초기화되지 않은 전역 변수에 액세스할 때 오류는 발생하지 않지만 결과는 다음과 같습니다: nil🎜🎜

while(condition) do statements end


- 🎜
..
두 문자열 연결 🎜 - 🎜
string.sub ()
는 문자열을 가로채는 데 사용됩니다. 🎜
--[[ 函数返回两个值的最大值 --]] function max(num1, num2) if (num1 > num2) then result = num1; else result = num2; end return result; end -- 调用函数 print("两值比较最大值为 ",max(10,4)) print("两值比较最大值为 ",max(5,6))
- 🎜s: 가로채는 문자열 🎜 < li>🎜i: 차단 시작 위치; 🎜
- 🎜j: 차단 끝 위치, 기본값은 -1, 마지막 문자 🎜
string. )
는 문자열 검색에 사용됩니다🎜<dependency> <groupId>org.luaj</groupId> <artifactId>luaj-jse</artifactId> <version>3.0.1</version> </dependency>
- 🎜지정된 대상 문자열 str에서 지정된 내용 substr을 검색합니다. 일치하는 부분 문자열이 발견되면 시작 부분 하위 문자열의 인덱스와 끝 인덱스가 반환됩니다. 존재하지 않으면 nil이 반환됩니다. 🎜
- 🎜
init
는 검색 시작 위치를 지정합니다. 기본값은 1입니다. 음수일 수 있으며 뒤에서 앞으로 세는 문자 수를 나타냅니다. 🎜 - 🎜
plain
은 단순 모드를 사용할지 여부를 나타내며, 기본값은 false이고, true는 하위 문자열에 대한 단순 검색만 수행하고, false는 일반 패턴 일치를 사용함을 나타냅니다. 🎜
then
을 따라야 하며 흐름 제어는 end
로 끝납니다. 🎜package com.saint.base.lua; import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.JsePlatform; public class LuaString { public static void main(String[] args) { String luaStr = "print 'Saint is best man'"; Globals globals = JsePlatform.standardGlobals(); LuaValue luaValue = globals.load(luaStr); luaValue.call(); } }
package com.saint.base.lua; import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.JsePlatform; import java.io.FileNotFoundException; public class LuaFile { public static void main(String[] args) throws FileNotFoundException { // lua脚本的文件路径 String luaPath = "/xxxx/javaTest.lua"; Globals globals = JsePlatform.standardGlobals(); //加载脚本文件login.lua,并编译 globals.loadfile(luaPath).call(); LuaValue func1 = globals.get(LuaValue.valueOf("print1")); func1.call(); LuaValue func2 = globals.get(LuaValue.valueOf("print2")); String luaResp = func2.call(LuaValue.valueOf("saint-input-param")).toString(); System.out.println("lua file return is : " + luaResp); } }
2> 泛型for循环
通过一个迭代器函数来遍历所有值,类似 java 中的 foreach 语句;
语法格式:
--打印数组a的所有值 a = {"one", "two", "three"} for i, v in ipairs(a) do print(i, v) end
i 是数组索引值,v 是对应索引的数组元素值。
ipairs是Lua提供的一个迭代器函数,用来迭代数组。
2)while循环
while 循环语句在判断条件为 true 时会重复执行循环体语句。
语法格式:
while(condition) do statements end
statements(循环体语句) 可以是一条或多条语句,condition(条件) 可以是任意表达式;
在 condition(条件) 为 true 时执行循环体语句。
3)break提前退出循环
和Java中的break一个作用,用于退出当前循环或语句;
7、函数
在Lua中,函数是对语句和表达式进行抽象的主要方法。类似于Java中的方法。
Lua 函数主要有两种用途:
完成指定的任务,这种情况下函数作为调用语句使用;
计算并返回值,这种情况下函数作为赋值语句的表达式使用;
函数的编写方式如下:
--[[ 函数返回两个值的最大值 --]] function max(num1, num2) if (num1 > num2) then result = num1; else result = num2; end return result; end -- 调用函数 print("两值比较最大值为 ",max(10,4)) print("两值比较最大值为 ",max(5,6))
三、Java中执行Lua脚本
Java中执行Lua脚本有两种方式:字符串的方式、文件的方式;
Java中想要执行LUA脚本,首先需要在pom中引入相关依赖:
<dependency> <groupId>org.luaj</groupId> <artifactId>luaj-jse</artifactId> <version>3.0.1</version> </dependency>
1、字符串方式
对于简单的lua脚本,可以直接用java字符串写;
package com.saint.base.lua; import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.JsePlatform; public class LuaString { public static void main(String[] args) { String luaStr = "print 'Saint is best man'"; Globals globals = JsePlatform.standardGlobals(); LuaValue luaValue = globals.load(luaStr); luaValue.call(); } }
控制台输出:
2、文件方式
对于一些比较常用的、复杂的脚本可以选择存放在文件中,在Java中再调用lua文件;
package com.saint.base.lua; import org.luaj.vm2.Globals; import org.luaj.vm2.LuaValue; import org.luaj.vm2.lib.jse.JsePlatform; import java.io.FileNotFoundException; public class LuaFile { public static void main(String[] args) throws FileNotFoundException { // lua脚本的文件路径 String luaPath = "/xxxx/javaTest.lua"; Globals globals = JsePlatform.standardGlobals(); //加载脚本文件login.lua,并编译 globals.loadfile(luaPath).call(); LuaValue func1 = globals.get(LuaValue.valueOf("print1")); func1.call(); LuaValue func2 = globals.get(LuaValue.valueOf("print2")); String luaResp = func2.call(LuaValue.valueOf("saint-input-param")).toString(); System.out.println("lua file return is : " + luaResp); } }
lua脚本文件:
控制台输出:
3、Luaj概述
Luaj在包装执行具体的Lua代码时, 有三种不同的模式;
纯脚本解析执行(不选用任何Compiler)
To Lua字节码(LuaC, lua-to-lua-bytecode compiler)(默认选用)
To Java字节码(LuaJC, lua-to-java-bytecode compiler)
Luaj中的Globals对象不是线程安全的, 因此最佳实践是每个线程一个Globals对象。
事实上, 可以采用ThreadLocal的方式来存储该对象。
2)性能问题
Lua脚本在JAVA中运行,相比于直接运行Java代码会慢很多,大约1000倍。
四、Redis + Lua(EVAL命令)
在使用Redisson、Jedis+Lua时,我们可以通过redis客户端集成的、手写的LUA脚本来保证一系列命令在Redis中可以"原子执行"。
在redis执行lua脚本时,相当于一个redis级别的锁,不能执行其他操作,类似于原子操作,这也是redisson实现的一个关键点。
比如Redisson中的lua脚本:
Redisson如何实现分布式锁,可以看文章:https://www.yisu.com/article/277312.htm
lua脚本中有如下几个概念:
redis.call():执行redis命令。
KEYS[n]:指脚本中第n个参数,比如KEYS[1]指脚本中的第一个参数。
ARGV[n]:指脚本中第n个参数的值,比如ARGV[1]指脚本中的第一个参数的值。
返回值中nil与false同一个意思。
1、EVAL命令
redis2.6.0版本起 采用内置的Lua解释器 通过EVAL命令去执行脚本;
redis中的EVAL命令可以用于执行一段lua代码。命令格式如下:
第一个参数script:表示lua脚本的内容;
第二参数numkeys:表示有多少个键值对。
其余参数:先把numkeys个key列出来,再把numkeys个arg列出来。
Lua脚本中可以使用2个函数调用redis命令;
redis.call()
redis.pcall()
redis.call()与redis.pcall()相似,二者唯一不同之处:
如果执行的redis命令执行失败,redis.call()将产生一个Lua error,从而迫使EVAL命令返回一个错误给命令的调用者;
然而redis.pcall()将会捕捉这个错误,并返回代表这个错误的Lua表。
有那么一段逻辑;
如果Redis某个key的整数值 和 某个value相等,则将key对应的整数值 + 1000;否则将key的值设置为9999;
lua脚本执行命令如下:
EVAL "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('INCRBY', KEYS[1], 1000); else redis.call('set', KEYS[1], 9999); return nil; end;" 1 test 100
根据test值的不同,不同的执行结果如下:
위 내용은 Java 생태계/Redis에서 Lua 스크립트를 사용하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











Java 8은 스트림 API를 소개하여 데이터 컬렉션을 처리하는 강력하고 표현적인 방법을 제공합니다. 그러나 스트림을 사용할 때 일반적인 질문은 다음과 같은 것입니다. 기존 루프는 조기 중단 또는 반환을 허용하지만 스트림의 Foreach 메소드는이 방법을 직접 지원하지 않습니다. 이 기사는 이유를 설명하고 스트림 처리 시스템에서 조기 종료를 구현하기위한 대체 방법을 탐색합니다. 추가 읽기 : Java Stream API 개선 스트림 foreach를 이해하십시오 Foreach 메소드는 스트림의 각 요소에서 하나의 작업을 수행하는 터미널 작동입니다. 디자인 의도입니다

간단해진 Java: 강력한 프로그래밍을 위한 초보자 가이드 소개 Java는 모바일 애플리케이션에서 엔터프라이즈 수준 시스템에 이르기까지 모든 분야에서 사용되는 강력한 프로그래밍 언어입니다. 초보자의 경우 Java의 구문은 간단하고 이해하기 쉬우므로 프로그래밍 학습에 이상적인 선택입니다. 기본 구문 Java는 클래스 기반 객체 지향 프로그래밍 패러다임을 사용합니다. 클래스는 관련 데이터와 동작을 함께 구성하는 템플릿입니다. 다음은 간단한 Java 클래스 예입니다. publicclassPerson{privateStringname;privateintage;

Java는 초보자와 숙련된 개발자 모두가 배울 수 있는 인기 있는 프로그래밍 언어입니다. 이 튜토리얼은 기본 개념부터 시작하여 고급 주제를 통해 진행됩니다. Java Development Kit를 설치한 후 간단한 "Hello, World!" 프로그램을 작성하여 프로그래밍을 연습할 수 있습니다. 코드를 이해한 후 명령 프롬프트를 사용하여 프로그램을 컴파일하고 실행하면 "Hello, World!"가 콘솔에 출력됩니다. Java를 배우면 프로그래밍 여정이 시작되고, 숙달이 깊어짐에 따라 더 복잡한 애플리케이션을 만들 수 있습니다.

캡슐은 3 차원 기하학적 그림이며, 양쪽 끝에 실린더와 반구로 구성됩니다. 캡슐의 부피는 실린더의 부피와 양쪽 끝에 반구의 부피를 첨가하여 계산할 수 있습니다. 이 튜토리얼은 다른 방법을 사용하여 Java에서 주어진 캡슐의 부피를 계산하는 방법에 대해 논의합니다. 캡슐 볼륨 공식 캡슐 볼륨에 대한 공식은 다음과 같습니다. 캡슐 부피 = 원통형 볼륨 2 반구 볼륨 안에, R : 반구의 반경. H : 실린더의 높이 (반구 제외). 예 1 입력하다 반경 = 5 단위 높이 = 10 단위 산출 볼륨 = 1570.8 입방 단위 설명하다 공식을 사용하여 볼륨 계산 : 부피 = π × r2 × h (4

Spring Boot는 강력하고 확장 가능하며 생산 가능한 Java 응용 프로그램의 생성을 단순화하여 Java 개발에 혁명을 일으킨다. Spring Ecosystem에 내재 된 "구성에 대한 협약"접근 방식은 수동 설정, Allo를 최소화합니다.

스택은 Lifo (마지막으로, 첫 번째) 원칙을 따르는 데이터 구조입니다. 다시 말해서, 우리가 스택에 추가하는 마지막 요소는 제거 된 첫 번째 요소입니다. 우리가 스택에 요소를 추가 (또는 푸시) 할 때, 그것들은 상단에 배치됩니다. 즉, 무엇보다도

NEXO Exchange : Swiss cryptocurrency 대출 플랫폼 심층 분석 Nexo는 암호 화폐 대출 서비스를 제공하는 플랫폼으로, 40 개 이상의 암호 자산, 피아트 통화 및 Stablecoins의 모기지 및 대출을 지원합니다. 그것은 유럽과 미국 시장을 지배하며 플랫폼의 효율성, 보안 및 준수를 개선하기 위해 노력하고 있습니다. 많은 투자자들은 Nexo Exchange가 등록되는 위치를 알고 싶어하며 답은 스위스입니다. Nexo는 2018 년 Swiss Fintech Company Credissimo에 의해 설립되었습니다. Nexo Exchange 지리적 위치 및 규정 : Nexo는 잘 알려진 암호 화폐 친화적 인 지역 인 스위스 주 Zug에 본사를두고 있습니다. 이 플랫폼은 다양한 정부의 감독과 적극적으로 협력하며 미국 금융 범죄 법 집행 네트워크 (Fincen) 및 캐나다 금융에있었습니다.

Redis 데이터베이스를 효과적으로 모니터링하는 것은 최적의 성능을 유지하고 잠재적인 병목 현상을 식별하며 전반적인 시스템 안정성을 보장하는 데 필수적입니다. Redis 내보내기 서비스는 다음을 사용하여 Redis 데이터베이스를 모니터링하도록 설계된 강력한 유틸리티입니다.
