当前位置: 首页 > news >正文

Reactor 瞬态错误

在响应式编程中,retryWhen 操作符通过 RetrySignal 接口提供了对重试行为的精细控制,特别是在处理 瞬态错误(transient errors) 时。瞬态错误是指那些在一段时间内发生,但随后会自行恢复的错误,例如网络请求失败后服务器短暂不可用,但随后恢复正常。在这种情况下,我们希望每个错误“爆发”(burst)都能独立处理,而不是将前一次的重试状态带入下一次。


1. 瞬态错误的定义与场景

瞬态错误通常表现为短暂的失败,随后系统会恢复。例如,一个 HTTP 请求源可能会在某些条件下连续失败两次,然后恢复正常。这种模式在长期运行的流(如 Kafka 消费者、HTTP 请求等)中非常常见。


2. RetrySignal 的作用

RetrySignalretryWhen 操作符中用于表示重试状态的接口。它提供了两个关键方法:

  • totalRetries():返回到目前为止的总重试次数(单调递增)。
  • totalRetriesInARow():返回当前连续失败的次数。如果在重试中成功恢复(即接收到 onNext 而不是 onError),这个值会被重置为 0。

这个 totalRetriesInARow() 的值是处理瞬态错误的关键。它允许我们区分“连续失败”和“独立失败”,从而实现更合理的重试策略。


3. transientErrors(boolean) 配置的作用

当在 RetrySpecRetryBackoffSpec 中设置 transientErrors(true) 时,重试策略将使用 totalRetriesInARow() 来计算重试次数。这意味着:

  • 每次重试失败后,如果成功恢复(即接收到 onNext),则 totalRetriesInARow() 会被重置为 0。
  • 每次“爆发”(即连续失败)都会被独立处理,重试次数不会累积。

这种配置特别适用于处理瞬态错误,例如网络请求失败后服务器短暂不可用的情况。


4. 示例代码解析

// 用于生成数据和控制流的辅助变量
final AtomicInteger transientHelper = new AtomicInteger();
// 模拟HTTP请求的Flux数据流
Supplier<Flux<Integer>> httpRequest = () ->Flux.generate(sink -> {int i = transientHelper.getAndIncrement();if (i == 10) {sink.next(i);sink.complete();}else if (i % 3 == 0) {sink.next(i);}else {sink.error(new IllegalStateException("Transient error at " + i));}});
// 用于统计错误次数的变量
AtomicInteger errorCount = new AtomicInteger();
// 添加错误处理逻辑的Flux
Flux<Integer> transientFlux = httpRequest.get().doOnError(e -> errorCount.incrementAndGet());// 使用retryWhen进行重试,最多重试2次,并且认为所有错误都是暂时性的
transientFlux.retryWhen(Retry.max(2).transientErrors(true)).blockLast();
assertThat(errorCount).hasValue(6);
  • doOnError:用于统计错误次数。
  • retryWhen(Retry.max(2).transientErrors(true))
    • Retry.max(2) 表示最多重试 2 次。
    • transientErrors(true) 表示启用瞬态错误处理模式。
  • blockLast():等待整个流完成。
  • assertThat(errorCount).hasValue(6):验证总共发生了 6 次错误,说明重试机制成功处理了 6 次错误。

5. 关键区别:启用 transientErrors(true) 与不启用

  • 启用 transientErrors(true)

    • 每次重试失败后,如果成功恢复,totalRetriesInARow() 会被重置为 0。
    • 每次“爆发”(连续失败)都会被独立处理,重试次数不会累积。
    • 最终成功完成,错误次数为 6 次。
  • 不启用 transientErrors(true)

    • 重试次数是单调递增的,不会重置。
    • 如果第二次“爆发”导致重试次数超过 2 次,整个序列将失败。

6. 总结

  • retryWhen 通过 RetrySignal 提供了对重试行为的精细控制。
  • totalRetriesInARow() 是处理瞬态错误的关键,它允许我们区分“连续失败”和“独立失败”。
  • transientErrors(true) 配置使得每次“爆发”都能独立处理,重试次数不会累积,从而避免了因前一次失败而放弃后续重试的问题。
  • 这种机制特别适用于处理网络请求、数据库连接等可能遇到瞬态错误的场景。
http://www.lqws.cn/news/582877.html

相关文章:

  • 企业自建云概念解读|私有云、专有云、混合云、分布式云、企业云
  • go 语言大小写SpecialCase转换
  • window显示驱动开发—全屏模式
  • [论文阅读] Neural Architecture Search: Insights from 1000 Papers
  • Apache Seata < 2.3.0 raft反序列化漏洞
  • Clickhouse源码分析-TTL执行流程
  • 【Debian】1- 安装Debian到物理主机
  • 解决 VS Code Remote-SSH “无法安装 VS Code 服务器“ 错误的完整指南
  • 【RTSP从零实践】3、实现最简单的传输H264的RTSP服务器
  • 刚体模拟的核心流程:从物理建模到计算执行的全步骤解析
  • PCL点云库入门(第21讲)——PCL库点云特征之RSD特征描述Radius-based Surface Descriptor(RSD)
  • java JNDI高版本绕过 工具介绍 自动化bypass
  • jvm的调优命令jstack打印堆栈信息阐述以及调优
  • Android 四大组件
  • [6-02-01].第05节:配置文件 - YAML配置文件语法
  • xml.etree.ElementTree.ParseError: parsing finished: 错误原因定位
  • [创业之路-453]:企业经营层 - 红海思维 VS 蓝海思维全方位比较
  • vue中表尾合计
  • python训练day45 Tensorborad使用介绍
  • 【数据挖掘】数据挖掘综合案例—银行精准营销
  • UserWarning: Module “zipline.assets“ not found解决方法
  • 自由学习记录(65)
  • ThreadLocal、InheritableThreadLocal与TransmittableThreadLocal深度解析
  • 【Linux】网络基础
  • Git 常用命令、常用错误的总结
  • Kotlin空安全与异常处理
  • 国内Oracle大师认证
  • 深入比较 Gin 与 Beego:Go Web 框架的两大选择
  • 《燕云十六声》全栈技术架构深度解析
  • DFMEA检查表模板下载