Jedis不支持Lua脚本自动重试和连接自动归还,需手动封装重试逻辑并确保每次eval后通过try-with-resources或finally归还连接;失败原因包括连接重置、脚本超时、认证失败及集群重定向等。

直接结论:Jedis 本身不提供 Lua 脚本自动重试,也不自动管理连接归还;重试逻辑必须手动封装,连接池复用依赖严格调用 jedis.close() 或 pool.returnResource()(旧版) / try-with-resources(新版)。
为什么 eval 失败后不能靠 Jedis 自动重试
Jedis 的 eval 方法是纯命令转发,底层调用 Protocol.sendCommand 后直接解析响应。它不会捕获 JedisConnectionException、JedisDataException 或超时异常并重试——哪怕你传的是 SHA1 哈希值、脚本已预加载,只要连接断了或 Redis 返回 NOAUTH/BUSY,就原样抛出异常。
常见触发点包括:
- Redis 主从切换瞬间,连接被服务端主动关闭,
eval抛JedisConnectionException: java.net.SocketException: Connection reset - 脚本执行超时(
lua-time-limit配置),返回ERR BUSY Redis is busy running a script - 集群模式下 key 不在当前节点,报
MOVED或ASK错误(此时UnifiedJedis会重定向,但原始Jedis不会)
手动实现带重试的 Lua 执行(含连接池安全归还)
核心原则:每次 eval 必须绑定一个明确生命周期的 Jedis 实例,且无论成功失败,都必须确保连接归还到池中。推荐用 try-with-resources(Jedis ≥ 3.0)或显式 finally 块。
示例代码(使用 JedisPool + 指数退避重试):
jedis.close()










