Redis中Lua无法读取Go结构体routeVersion字段的问题及解决
Redis Lua脚本读取Go结构体JSON字段为nil的问题解决
问题场景
通过Lua脚本将Go结构体经cjson.encode存入Redis后,使用另一Lua脚本读取并解析JSON时,始终无法获取到routeVersion字段值(返回nil)。本地测试环境一切正常,但预发布环境出现该异常。
原实现代码
存入Redis的Lua脚本
redis.call('SET', KEYS[1], cjson.encode(ARGV[1]))
Go结构体定义
type InviteInfo struct { // 其他字段省略 MaxPeers int32 `json:"maxPeers"` RouteVersion int32 `json:"routeVersion"` // 其他字段省略 }
查询校验的Lua脚本
local data = redis.call('GET', KEYS[1]) -- 解析JSON local inviteInfo = cjson.decode(data) -- 对比路由版本 if tonumber(inviteInfo['routeVersion']) ~= tonumber(ARGV[1]) then return "route version mismatch" end
解决流程
调整数据存入顺序,将JSON序列化步骤移至Go侧:
- 在Go代码中使用
json.Marshal()将InviteInfo结构体序列化为标准JSON字符串 - 将该字符串直接传入Lua脚本,调用
SET命令存入Redis
修改后的存入Lua脚本简化为:
redis.call('SET', KEYS[1], ARGV[1])
原因分析
对比Redis中存储的数据:
- 原流程存储的是双重转义后的JSON:
{\"routeVersion\":1},Lua的cjson.decode解析时会将整个内容识别为字符串而非JSON对象,导致无法读取字段 - 修改后存储的是标准JSON格式:
{"routeVersion":1},cjson.decode能正确解析为JSON对象,正常读取routeVersion字段值
内容的提问来源于stack exchange,提问作者shawn
相关产品推荐
相关产品推荐

