Lambda重试器将重试行为抽象为可配置、可组合、可监控的一等公民,通过Supplier/Function封装幂等动作,用Predicate/BiFunction等定义策略,泛型执行器统一处理循环、日志与指标,并支持超时、熔断等Lambda装饰器动态增强。
用Lambda表达式实现逻辑重试器,关键不是反复调用,而是把“重试行为”本身变成可配置、可组合、可监控的一等公民。它要保护的不是变量本身,而是变量参与的业务动作——比如扣款、发通知、更新状态——这些动作一旦失败,必须按策略重试,同时避免重复执行副作用。
用Function + Supplier封装可重入的动作
不要直接在重试逻辑里写业务代码。把需要保护的操作包装成Supplier或Function,确保它天然支持多次执行:
用
Supplier
表示无参、有返回值的动作,如
用
Function
表示带上下文的计算,如
所有动作必须是幂等的:同一输入始终产生相同结果,不依赖外部状态突变
定义重试策略为可复用的Lambda组合
策略不是硬编码的sleep+for循环,而是由Predicate、BiFunction、UnaryOperator等函数式接口拼装而成:
是否重试?
用Predicate判断异常类型:
下一次延迟多久?
用BiFunction实现退避算法:
最大重试次数?
作为参数传入,不写死在逻辑里;配合Stream.iterate生成重试序列更清晰
统一执行器:串起动作、策略与可观测性
写一个泛型重试执行器,接收动作、策略和上下文,内部完成循环、捕获、延迟、日志、指标上报:
签名示例:
每次执行前记录
,失败后记录
并带上异常分类
成功时统计
,用于后续优化策略
支持传入ThreadLocal上下文或MDC,让日志能追踪完整链路
结合装饰器做轻量级增强
原始重试逻辑不关心超时、熔断、限流。用Lambda装饰器动态叠加能力:
超时包装:
熔断包装:
每个装饰器都是独立Lambda,可自由组合、单元测试、开关控制
Supplier chargeAction = () -> paymentService.charge(orderId, amount); Function apiCall = ctx -> httpClient.post(ctx.url(), ctx.body()); Predicate shouldRetry = t -> t instanceof TimeoutException || t instanceof NetworkException; (attempt, ex) -> Duration.ofMillis((long) Math.pow(2, attempt) * 100) T executeWithRetry(Supplier action, RetryPolicy policy, String operationName) retry.attempt.startretry.failureretry.success.after_n_attemptsSupplier timeoutWrapped = withTimeout(action, Duration.ofSeconds(5)) Supplier circuitWrapped = withCircuitBreaker(timeoutWrapped, breaker) 