redisTemplate执行lua脚本报错‘for‘ initial value must be a number

1.lua脚本以及springboot代码

java 复制代码
    /**
     * 批量设置Bit位(start到end置1)
     */
    private void batchSetBit(String bitKey, long start, long end) {
        String luaScript = """
                    local key = KEYS[1]
                     local start_val = ARGV[1]
                     local end_val = ARGV[2]
                     local start_num = tonumber(start_val)
                     local end_num = tonumber(end_val)
                     local count = 0
                     for i = start_num, end_num do
                         redis.call('SETBIT', key, i, 1)
                         count = count + 1
                     end
                     return count
                """;
        DefaultRedisScript<Long> script = new DefaultRedisScript<>();
        script.setScriptText(luaScript);
        script.setResultType(Long.class);
        redisTemplate.execute(script, Collections.singletonList(bitKey), String.valueOf(start), String.valueOf(end));
    }

报错: @user_script:7: user_script:7: 'for' initial value must be a number

分析,首先修改lua脚本,打印出传递的值

java 复制代码
String luaScript = """
                    local key = KEYS[1]
                     local start_val = ARGV[1]
                     local end_val = ARGV[2]
                     local start_num = tonumber(start_val)
                     local end_num = tonumber(end_val)
                     if start_num == nil or end_num == nil then
                         return redis.error_reply("Invalid range: start=" .. tostring(start_val) .. ", end=" .. tostring(end_val))
                     end
                     local count = 0
                     for i = start_num, end_num do
                         redis.call('SETBIT', key, i, 1)
                         count = count + 1
                     end
                     return count
                """;

重新执行后报错: Invalid range: start="0", end="2999"

问题 1:Value 序列化器不兼容 Lua 脚本调用(根源问题)

你的 redisTemplate 中 valueSerializer 使用了 Jackson2JsonRedisSerializer(JSON 序列化),而 Lua 脚本需要接收纯字符串格式的数字(如 "0" "999"),但 JSON 序列化会把字符串参数包装成带引号的 JSON 字符串(比如传 "0" 会被序列化成 ""0""),导致 Lua 中 tonumber(ARGV1) 解析失败,这也是之前报 Invalid numeric arguments 的根本原因。

2.解决方法

(1)使用StringRedisTemplate

默认序列化器 全链路 StringRedisSerializer(纯字符串)

参数传递形式 输入 "0" → 直接转字节数组 48(纯 UTF-8 编码)

(2)将参数的双引号去掉

bash 复制代码
    start_val = string.gsub(start_val, "^[\"']*(.-)[\"']*$", "%1")
    end_val = string.gsub(end_val, "^[\"']*(.-)[\"']*$", "%1")
相关推荐
笨鸟先飞的橘猫1 天前
skynet热更新实现问题与排错记录
学习·lua·skynet
骑着蜗牛撵大象3273 天前
设备监控数据存与查:Spring Boot 接入 TimescaleDB 超表的完整落地
android·spring boot·后端·springboot·时序数据库·es·设备监控
开开心心_Every5 天前
黄金价格软件国内外价格实时监控超方便
运维·服务器·游戏·智能手机·pdf·lua·perl
Dreamboat-L6 天前
日志级别基础 + Spring Boot 日志实践指南
java·服务器·数据库·java-ee·springboot
ab1237686 天前
Spring WebSocket(STOMP)
笔记·websocket·springboot·stomp
Java爱好狂.6 天前
挑战一周速通Spring+SpringBoot+SpringCloud!
java·后端·spring·springboot·架构师·java面试·java程序员
笨鸟先飞的橘猫6 天前
C 扩展开发指南:从 Lua 到 skynet 的完整链路
c语言·lua
撸串-研究生7 天前
社区流浪宠物领养救助系统【附源码】
mysql·springboot·宠物·社区公益服务
贾宝玉的玉宝贾8 天前
FreeSWITCH 简单图形化界面 70 - 监听/密语的lua脚本
开发语言·junit·lua·voip·freeswitch·sip·ippbx
BLUcoding11 天前
接口服务公网超时排查记录:SecureRandom 阻塞问题分析与解决
java·linux·springboot·aes·securerandom