方案一和方案二存在一个问题:
正常逻辑和重试逻辑强耦合,重试逻辑非常依赖正常逻辑的执行结果,对正常逻辑预期结果被动重试触发,对于重试根源往往由于逻辑复杂被淹没, 可能导致后续运维对于重试逻辑要解决什么问题产生不一致理解。
重试正确性难保证而且不利于运维,原因是重试设计依赖正常逻辑异常或重试根源的臆测
那有没有可以参考的方案实现正常逻辑和重试逻辑解耦,同时能够让重试逻辑有一个标准化的解决思路?
答案是有:那就是基于代理设计模式的重试工具,我们尝试使用相应工具来重构上述场景。
命令设计模式具体定义不展开阐述,主要该方案看中命令模式能够通过执行对象完成接口操作逻辑,同时内部封装处理重试逻辑,不暴露实现细节, 对于调用者来看就是执行了正常逻辑,达到解耦的目标,具体看下功能实现。(类图结构)
IRetry约定了上传和重试接口,其实现类OdpsRetry封装ODPS上传逻辑,同时封装重试机制和重试策略。与此同时使用recover方法在结束执行做恢复操作。
而我们的调用者LogicClient无需关注重试,通过重试者Retryer实现约定接口功能,同时 Retryer需要对重试逻辑做出响应和处理, Retryer具体重试处理又交给真正的IRtry接口的实现类OdpsRetry完成。
通过采用命令模式,优雅实现正常逻辑和重试逻辑分离,同时通过构建重试者角色,实现正常逻辑和重试逻辑的分离,让重试有更好的扩展性。