Jedis2.9执行lua脚本的问题

线上监控发现 jedis.evalsha(...) 有时会报错:

12-20 14:20:19 500 INFO keyword=Some(()
12-20 14:20:19 552 ERROR ERR Error running script (call to f_84d49c1a4ef53377d4c0c7cf685825cebdea31e8): @user_script:68: user_script:68: unfinished capture
redis.clients.jedis.exceptions.JedisDataException: ERR Error running script (call to f_84d49c1a4ef53377d4c0c7cf685825cebdea31e8): @user_script:68: user_script:68: unfinished capture
        at redis.clients.jedis.Protocol.processError(Protocol.java:127) ~[jedis-2.9.0.jar:na]
        at redis.clients.jedis.Protocol.process(Protocol.java:161) ~[jedis-2.9.0.jar:na]
        at redis.clients.jedis.Protocol.read(Protocol.java:215) ~[jedis-2.9.0.jar:na]
        at redis.clients.jedis.Connection.readProtocolWithCheckingBroken(Connection.java:340) ~[jedis-2.9.0.jar:na]
        at redis.clients.jedis.Connection.getOne(Connection.java:322) ~[jedis-2.9.0.jar:na]
        at redis.clients.jedis.Jedis.getEvalResult(Jedis.java:2731) ~[jedis-2.9.0.jar:na]
        at redis.clients.jedis.Jedis.evalsha(Jedis.java:2757) ~[jedis-2.9.0.jar:na]
        at redis.clients.jedis.Jedis.evalsha(Jedis.java:2751) ~[jedis-2.9.0.jar:na]

当传参为 ( 时, 执行lua脚本失败, 初步怀疑是lua特殊字符的问题, 请教老同学, 原来是 lua 模式匹配的问题(针对特殊字符)

Jedis2.9执行lua脚本的问题_第1张图片

后续测试发现 (, [, % 都会导致jedis异常, 其他特殊字符正常(怀疑跟lua的模式匹配有关系, 没有深究)

既然这样就要定义一个转义特殊字符的函数了

-- lua特殊字符%转义: ( ) . % + - \* ? \[ ^ $  
function string.escape(t) 
    --text = "( ) . % + - \* ? \[ ^ $"  
    local text = t  
    text = string.gsub(text, "%%", "%%%%")  
    text = string.gsub(text, "%(", "%%(")  
    text = string.gsub(text, "%)", "%%)")  
    text = string.gsub(text, "%.", "%%.")  
    text = string.gsub(text, "%+", "%%+")  
    text = string.gsub(text, "%-", "%%-")  
    text = string.gsub(text, "%\*", "%%\*")  
    text = string.gsub(text, "%?", "%%?")  
    text = string.gsub(text, "%\[", "%%\[")  
    text = string.gsub(text, "%^", "%%^")  
    text = string.gsub(text, "%$", "%%$")  
    return text  
end

-- string.find 触发模式匹配, 所以需要将特殊字符转义, 否则返回结果可能和预期不一致
-- 相当于 string.find("123(", "%(")
local match = string.find("123(", string.escape("("))

测试搞定!

你可能感兴趣的:(redis,lua)