西安制作网站软件,加盟创业商机网,自己干电商如何下手,做电影网站如何推广什么是lua脚本#xff1f;
lua语言是一个轻量级的脚本语言#xff0c;可以嵌入其他语言中使用#xff0c;调用宿主语言的功能。lua语法简单#xff0c;小巧#xff0c;源码一共才200多K#xff0c;本身不会有太强的功能#xff0c;很多的语言也支持lua语言#xff0c;…什么是lua脚本
lua语言是一个轻量级的脚本语言可以嵌入其他语言中使用调用宿主语言的功能。lua语法简单小巧源码一共才200多K本身不会有太强的功能很多的语言也支持lua语言比如redis、Nginx
redis语言中完美嵌入了lua脚本功能redis可以调用lua脚本中的apilua脚本也可以调用redis中的命令
redis调用lua脚本
在redis中调用lua脚本需要使用eval指令
127.0.0.1:6379eval return hello 0
hello调用lua脚本动态传入参数其中表达式script后面第一个参数nkey表示key的对应位置后面的表示key和对应的参数argv
# script脚本后面第一个参数1表示key为其后的第一个参数也就是1如何key后面的参数都是ARGV
127.0.0.1:6379eval if KEYS[1]1 then return ARGV[1] end return ARGV[2] 1 1 hello hi
hello
127.0.0.1:6379eval if KEYS[1]1 then return ARGV[1] end return ARGV[2] 1 1 hello hi
hilua脚本调用redis命令
使用lua调用redis的命令需要使用redis.call调用
# key为0表示能获取到锁
127.0.0.1:6379eval local key redis.call(exists,KEYS[1]) if key0 then return redis.call(set,KEYS[1],ARGV[1]) end return 1 1 orderId01 1写个lua脚本来实现一个简单的分布锁锁
private static final String LOCK_LUA_SCRIPT local lockParam redis.call(exists, KEYS[1])\n if lockParam 0 then\n redis.call(set, KEYS[1], ARGV[1])\n redis.call(expire, KEYS[1], ARGV[2])\n end\n return lockParam\n;简单实现抢单的业务 Autowiredprivate RedisTemplate redisTemplate;Testpublic void testLua() {Long orderId IdUtil.getSnowflake().nextId();String lockKey order:orderId;String requestId IdUtil.randomUUID();try {Long lock (Long) redisTemplate.execute(RedisScript.of(LOCK_LUA_SCRIPT, Long.class), Arrays.asList(lockKey), requestId, 30);// 抢得到锁if (lock 0) {// 模拟业务执行10sTimeUnit.MILLISECONDS.sleep(10*1000);}log.info(lock:[{}], lock);} catch (Exception e) {testRelease(lockKey, requestId);} finally {testRelease(lockKey, requestId);}}锁释放的也通过lua脚本实现主要是保证原子性 private String UNLOCK_LUA_SCRIPT if redis.call(get, KEYS[1]) ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end;Test
public void testRelease(String lockKey, String lockValue) {redisTemplate.execute(RedisScript.of(UNLOCK_LUA_SCRIPT, Long.class), Arrays.asList(lockKey), lockValue);
}Lua脚本使用场景
保证原子性地执行多个命令需要返回中间值组合编排后面的命令