CF.INFO 报错后 Mono 一直不结束
Lettuce 7.7 的 Reactive 复杂结果命令可能在服务端错误后等到 timeout。7.8.0 调整了错误检查顺序,恢复 onError;仍需处理原来的 Redis 错误。
Lettuce 的 Reactive CF.INFO 查询不存在的键时,服务端已经返回错误,Mono 却一直等到命令超时。同步或异步调用能够及时报错时,应检查 Reactive 复杂结果解析路径,而不只是增加超时时间。
Lettuce 7.7.0 的这条路径会在检查服务端错误之前解析结果,错误回复中的空数据触发了解析异常,却没有正常送达订阅者。这项修复包含在 7.8.0,已核对的 7.9.0 实现也先检查错误。
服务端有回复,订阅者仍可能等不到 onError
涉及的命令采用 EncodedComplexOutput 和复杂结果解析器,包括 CF.INFO、BF.INFO、TOPK.INFO、TOPK.LIST 等。问题发生在服务端返回错误时,不等于这些命令的每次调用都会挂起。
旧路径先调用结果的 get(),随后才检查 hasError()。错误回复没有正常结果数据,解析器因此抛出异常;此时命令包装器已经进入完成状态,后续异常处理没有再向 Reactive 订阅者发出应有的错误信号。
同步与异步路径先检查服务端错误,不会先解析这份错误载荷。所以同样的服务端错误,在不同接口中可能表现为立即失败或等待客户端超时。
正常的空回复又是另一种情况。不能把“没有结果”统一理解为错误,也不能只因为一个 Mono 等待,就认定一定经过了复杂解析器。
先核对命令、版本与原始错误
记录应用实际使用的 Lettuce 版本、出错命令和连接模式。确认服务端是否已经返回缺失键、错误类型、命令不支持等错误,再比较 Reactive 与非 Reactive 路径的表现。
涉及模块命令时,还要核对服务器或所接服务支持的命令。升级客户端会恢复错误送达,但不会在服务器上安装缺失的模块,也不会把错误类型的键变成合法输入。
如需制造错误样例,在隔离环境使用不存在的测试键,并设置有界的等待时间。这里不能通过生产写入或删除真实键来证明问题,更不能把等待直到默认超时当成没有服务端回复的证据。
采用包含修复的客户端
按项目的兼容要求升级到 Lettuce 7.8.0 或包含修复的后续版本,保留原依赖管理与可恢复构建。修复后的路径先检查 hasError(),将实际 Redis 错误交给 onError,再处理正常结果。
随后调整应用真正收到的 RedisCommandExecutionException:缺失键、错误类型、模块命令不支持等原因要分别处理。错误开始及时到达后,既有的重试与降级分支也会开始运行,应检查它们是否会反复调用同一条注定失败的命令。
有界的 Reactive 超时仍可保护调用方,但它不是这项解析错误的修复。增加一分钟的等待上限不会改变解析顺序;把调用换成事件循环上的阻塞命令,也可能引入新的等待问题。
验收已知错误能够在超时前到达错误处理分支,异常保留原来的 Redis 原因。同时检查正常结果和正常空结果仍能正确结束,不只验证错误样例。
需要撤回时恢复兼容的依赖集合和应用构建,保留等待上限及必要的错误记录。若升级后仍有 Reactive 请求超时,再根据实际命令、结果解码和网络状态调查,不能把所有超时都归到同一完成状态问题。


