千家信息网

SpringBoot如何通过redisTemplate调用lua脚本并打印调试信息到redislog

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,这篇文章将为大家详细讲解有关SpringBoot如何通过redisTemplate调用lua脚本并打印调试信息到redislog,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后
千家信息网最后更新 2026年11月01日SpringBoot如何通过redisTemplate调用lua脚本并打印调试信息到redislog

这篇文章将为大家详细讲解有关SpringBoot如何通过redisTemplate调用lua脚本并打印调试信息到redislog,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。

第一次写Lua脚本,并通过springboot的redisTemplate调用脚本,进行脚本与应用的交互。不熟悉真的折腾了好久,现在总结一下学习过程:

第一次写完lua时,想到的就是如何在应用调用脚本的时候,去调试脚本。在网上海搜了一把,能找到的有点相关的寥寥无几。

有一种方法是通过执行redis命令,调用redis客户端,加载lua脚本,然后出现基于命令行调试的交互界面,输入调试命令去调试脚本。如下:

在终端输入命令:redis-cli.exe --ldb --eval LimitLoadTimes.lua 1 mykey , myargv

--ldb:redis-cli.exe进行命令调试的必要参数

--eval:告诉redis客户端去加载Lua脚本,后面跟着的就是 lua脚本的路径(我是直接放在redis目录下),

1:传给Lua脚本的key的数量,我测试的时候是1

--mykey:自己传的一个key值,和前面的数量1对应

--myargv:自己传的除key外的参数,可以是多个

注,命令中的逗号不能忽略,并且前后要有一个空格

回车,如上图,本来以为可以进入调试,结果等了半天,一直没有出现交互的命令行界面,找了好久,还是没找到办法,结果只好先暂停(如果有大神遇到这种情况,跪求解~~)。换一种调试方式,把调试信息打在redis日志上。

下面是我自己调用脚本时,打印调试信息的方式,如果有更好的方式,请不吝赐教。

1、选择redisTemplate序列化方式

首先,创建一个redisTemplate,具体代码就不说了,这个比较简单。要注意的是,需要设置redisTemplate的序列化方式,springBoot默认是基于java jdk的序列化。通过这种序列化后的参数传到Lua脚本是,是无法正常打印到redis日志的,会出现乱码,而且参数如果传的是一个Map或List的话,不方便解析。并且这种序列化占用的字节比较大。所以改成JSON序列化,用FastJson实现。

下面贴上redis序列化代码:

public class FastJsonRedisSerializer implements RedisSerializer { public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8"); private Class clazz; public FastJsonRedisSerializer(Class clazz){ super(); this.clazz = clazz; } @Override public byte[] serialize(T t) throws SerializationException { return ofNullable(t) .map(r -> JSON.toJSONString(r, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET)) .orElseGet(() -> new byte[0]); } @Override public T deserialize(byte[] bytes) throws SerializationException { return Optional.ofNullable(bytes) .map(t -> JSON.parseObject(new String(t, DEFAULT_CHARSET), clazz)) .orElseGet(() -> null); }}

2、应用端加载脚本,并设置传递参数

在springboot中,是用 DefaultRedisScript 类来加载脚本的,并设置相应的数据类型来接收lua脚本返回的数据,这个泛型类在使用时设置泛型是什么类型,脚本返回的结果就是用什么类型接收。注意,该类只接收4种类型的返回类型,之前没注意,还纳闷为什么出错,看源码才晓得,截图,如下:

在lua脚本中,有两个全局的变量,是用来接收redis应用端传递的键值和其它参数的,分别为KEYS、ARGV。

在应用端传递给KEYS时是一个数组列表,在lua脚本中通过索引方式获取数组内的值。

在应用端,传递给ARGV的参数比较灵活,可以是多个独立的参数,但对应到Lua脚本中是,统一用ARGV这个数组接收,获取方式也是通过数组下标获取。

下面贴上应用端的测试代码:

@Service("luaScriptService")public class LuaScriptServiceImpl implements LuaScriptService{ @Autowired private RedisTemplate redisTemplate1; private DefaultRedisScript getRedisScript; @PostConstruct public void init(){ getRedisScript = new DefaultRedisScript(); getRedisScript.setResultType(List.class); getRedisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("luascript/LimitLoadTimes.lua"))); } @Override public void redisAddScriptExec(){ /** * List设置lua的KEYS */ List keyList = new ArrayList(); keyList.add("count"); keyList.add("rate.limiting:127.0.0.1"); /** * 用Mpa设置Lua的ARGV[1] */ Map argvMap = new HashMap(); argvMap.put("expire",10000); argvMap.put("times",10); /** * 调用脚本并执行 */ List result = redisTemplate1.execute(getRedisScript,keyList, argvMap); System.out.println(result); }}

代码中发送了两个key,还有一个map包装的argv,传递到Lua脚本中时,KEYS和ARGV接收到的是对象字符串,所以得用lua的库做相关的解码,我们发送的时候是用json序列化的,用Lua的库cjson可以转成json对象。下面贴上Lua脚本代码:

--获取KEYlocal key1 = KEYS[1]local key2 = KEYS[2]-- 获取ARGV[1],这里对应到应用端是一个List.-- 注意,这里接收到是的字符串,所以需要用csjon库解码成table类型local receive_arg_json = cjson.decode(ARGV[1])--返回的变量local result = {}--打印日志到reids--注意,这里的打印日志级别,需要和redis.conf配置文件中的日志设置级别一致才行redis.log(redis.LOG_DEBUG,key1)redis.log(redis.LOG_DEBUG,key2)redis.log(redis.LOG_DEBUG, ARGV[1],#ARGV[1])--获取ARGV内的参数并打印local expire = receive_arg_json.expirelocal times = receive_arg_json.timesredis.log(redis.LOG_DEBUG,tostring(times))redis.log(redis.LOG_DEBUG,tostring(expire))--往redis设置值redis.call("set",key1,times)redis.call("incr",key2)redis.call("expire",key2,expire)--用一个临时变量来存放json,json是要放入要返回的数组中的local jsonRedisTemp={}jsonRedisTemp[key1] = redis.call("get",key1)jsonRedisTemp[key2] = redis.call("get", key2)jsonRedisTemp["ttl"] = redis.call("ttl",key2)redis.log(redis.LOG_DEBUG, cjson.encode(jsonRedisTemp))result[1] = cjson.encode(jsonRedisTemp) --springboot redistemplate接收的是List,如果返回的数组内容是json对象,需要将json对象转成字符串,客户端才能接收result[2] = ARGV[1] --将源参数内容一起返回redis.log(redis.LOG_DEBUG,cjson.encode(result)) --打印返回的数组结果,这里返回需要以字符返回return result

3、设置日志级别

代码中,redis.log()函数向运日志中输出信息,这里要注意一下,函数里面设置的日志级别要和redis.conf配置文件中设置的日志级别一样才能正常打印到文件,这里我是设置成了deubg级别。这里可设置的级别有4种,分别如下:

redis.LOG_DEBUG redis.LOG_VERBOSE redis.LOG_NOTICE redis.LOG_WARNING

在应用端,我们设置接收返回的数据类型是List,所以在Lua脚本中,返回的类型用table与之对应,并且放到table变量中的内容,得是字符串,应用端才能通过反序列化,正常解析。下图是输出lua返回值的打印信息:

至此,结束,希望也能对其遇到相同问题的朋友有所帮助。

关于SpringBoot如何通过redisTemplate调用lua脚本并打印调试信息到redislog就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。

脚本 参数 应用 序列 日志 类型 命令 方式 级别 信息 代码 数组 内容 字符 变量 字符串 对象 结果 客户 客户端 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 互联网和科技技术 苏州互联网科技贷款公司 无线互联网科技 团飞科技与伯堂互联网服务平台 常德市电业局互联网科技部 赶超互联网科技 微信多开 互联网媒体平台算高科技产业 互联网科技研发水平 互联网保险科技创业 民营互联网公司国防科技 西安小鹰速贷互联网科技有限公司 为客找房互联网科技公司怎么样 合肥互联网科技公司公章图片 江苏互联网智能科技软件 张召忠谈中国互联网科技 上海互联网科技公司ppt 图游互联网科技 普陀区互联网教育科技管理办法 绵阳真晨互联网科技有限公司 互联网科技创新方面的资料 深圳九邦互联网科技有限公司 互联网科技公司的优势 礼当家互联网科技 赫美联合互联网科技 狮子座互联网科技培训 人人互联网科技是培训 丰台科技园 互联网公司 广西拼得多互联网科技有限公司 互联网科技人工智能实验室 迪庆互联网科技招生
0