lua脚本~ Redis调用

lua脚本~ Redis调用lua 脚本 Redis 调用参考资料 redis 常见命令官方调用 lua 文档 redis 菜鸟教程 lua 菜鸟教程其他 https www cnblogs com kaituorenshe p 11098194 htmlhttps bl

大家好,欢迎来到IT知识分享网。

lua脚本~ Redis调用

参考资料:

redis常见命令

官方调用lua文档

redis菜鸟教程

lua菜鸟教程

其他:

https://www.cnblogs.com/kaituorensheng/p/11098194.html

https://blog.csdn.net/z/article/details/

前言

前言的前言

一句话,因为要用所以学习简单粗暴

前言body

本次仅学习如何使用redis调用lua脚本(含springboot调用方式),lua脚本如何写以后有时间在玩。

本次测试的lua脚本

写redis锁时经常使用的一个脚本:

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

Redis客户端操作

我这里的客户端用的windows的,将准备好的lua脚本放在自己指定的文件夹

# 链接redis服务器 > redis-cli.exe -h 127.0.0.1 -p 6379 # 设置测试键值 > set jimmyTestRedisLock Y > OK # 检查设置是否成功 > get jimmyTestRedisLock > "Y" # 先执行一个测试脚本 > eval "return {KEYS[1],ARGV[1]}" 1 key1 first > 1) "key1" > 2) "first" # 执行我们的测试脚本 > eval E:/tmp/unlock.lua 1 jimmyTestRedisLock Y > (error) ERR Error compiling script (new function): user_script:1: ' 
  
    ' expected near '/' 
  

报错了!!! why ??? 这个符合eval语法吖?

其实,这里面有一个问题就是如果想要直接执行文件,就不需要进入redis-client

# 直接在cmd中(linux就是终端里调用 redis-cli 命令即可) > redis-cli.exe -h 127.0.0.1 -p 6379 --eval E:/tmp/unlock.lua 1 jimmyTestRedisLock Y > 1 # 检查脚本执行是否成功 > get jimmyTestRedisLock # 完美 > (nil) 

当然如果想要在reids-client内执行怎么办呢?

  • 这里就需要使用 SCRIPT LOAD
# 将lua加载到redis服务中 执行完会返回一段SHA码 > redis-cli script load "$(cat 【替换成编写的lua文件名】.lua)" # EvalSHA命令 > evalsha SHA码 

Spring boot中执行lua脚本

这里展示部分代码

将脚本放在resouces 文件下 lua/unlock.lua

@Override public boolean tryLock() { log.info("RedisLock tryLock()"); try{ String uuid = UUID.randomUUID().toString(); // 序列化值多双引号问题,指定序列化方式 redisTemplate.setValueSerializer(new StringRedisSerializer()); redisTemplate.opsForValue().set(lock, uuid, expiresTime, TimeUnit.SECONDS); local.set(uuid); }catch (Exception e){ log.error("RedisLock tryLock() ex", e); return false; } log.info("RedisLock tryLock() success"); return true; } / * 释放锁 */ @Override public void unlock() { log.info("RedisLock tryLock(1,2) success"); DefaultRedisScript unlockScript = new DefaultRedisScript 
  
    (); unlockScript.setResultType(Long.class); unlockScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("lua/unlock.lua"))); List 
   
     keys = new ArrayList<>(); keys.add(lock); List 
    
      args = new ArrayList<>(); args.add(local.get()); // 集群模式下这样使用会报错 org.springframework.dao.InvalidDataAccessApiUsageException: EvalSha is not supported in cluster environment. // Long res = (Long) redisTemplate.execute(unlockScript, keys,local.get()); Long res = (Long) redisTemplate.execute(new RedisCallback 
     
       () { @Override public Long doInRedis(RedisConnection connection) throws DataAccessException { Object nativeConnection = connection.getNativeConnection(); // 集群模式和单机模式虽然执行脚本的方法一样,但是没有共同的接口,所以只能分开执行 // 集群模式 if (nativeConnection instanceof JedisCluster) { return (Long) ((JedisCluster) nativeConnection).eval(unlockScript.getScriptAsString(), keys, args); } // 单机模式 else if (nativeConnection instanceof Jedis) { return (Long) ((Jedis) nativeConnection).eval(unlockScript.getScriptAsString(), keys, args); } return 0L; } }); log.info("RedisLock unlock res:" + res); if(res == 1) { log.info("RedisLock unlock success"); } else { log.info("RedisLock unlock fail"); } } 
      
     
    
  

测试代码:

import ...RedisLock; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.test.context.web.WebAppConfiguration; import javax.annotation.Resource; @RunWith(SpringRunner.class) @SpringBootTest @WebAppConfiguration public class RedisLockTest { @Autowired private RedisLock redisLock; @Test public void testRedis(){ System.out.println(redisLock.tryLock()); redisLock.unlock(); } } 

测试控制台结果。当然也需要在redis-client中检查下是否是正确的结果

2020-12-09 15:20:46.310 INFO [ybyy-customer,] 10084 — [ main] c.s.y.c.service.impl.ClaimServiceImpl : RedisLock tryLock()
2020-12-09 15:20:46.361 INFO [ybyy-customer,] 10084 — [ main] c.s.y.c.service.impl.ClaimServiceImpl : RedisLock tryLock() success
true
2020-12-09 15:20:46.362 INFO [ybyy-customer,] 10084 — [ main] c.s.y.c.service.impl.ClaimServiceImpl : RedisLock tryLock(1,2) success
2020-12-09 15:20:46.409 INFO [ybyy-customer,] 10084 — [ main] c.s.y.c.service.impl.ClaimServiceImpl : RedisLock unlock res:1
2020-12-09 15:20:46.409 INFO [ybyy-customer,] 10084 — [ main] c.s.y.c.service.impl.ClaimServiceImpl : RedisLock unlock success

封面图(侵权删)

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/173076.html

(0)
上一篇 2025-03-11 11:15
下一篇 2025-03-11 11:25

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信