云计算百科
云计算领域专业知识百科平台

Dubbo 默认超时重试:把下游打雪崩的隐形放大器

一次梳理 RPC 超时配置时发现:@DubboReference 的默认重试,在高峰期会把「刚好变慢」的那一小段流量放大成三倍,再通过同步链路拖垮下游。文中数字来自当时的推演举例,系统名已脱敏。 适合做过 Dubbo / Feign 调用、但没认真算过「重试预算」的同学。

文章目录

    • 一、背景:默认值往往最危险
    • 二、问题:放大是怎么算出来的
    • 三、方案对比:关掉、改配置,还是换策略
    • 四、落地:配置、预算与幂等
      • 4.1 把默认改成「显式」
      • 4.2 算清楚「重试预算」
      • 4.3 和熔断、限流怎么配合
      • 4.4 业务层:幂等键比「多试两次」更重要
    • 五、排查清单:怀疑「被重试放大」时看什么
    • 六、小结

一、背景:默认值往往最危险

微服务里最常见的一句话是:「超时了就再试一次。」听起来合理,落到 Dubbo 上却有两个容易被忽略的事实:

  • 默认就会重试——不是你显式打开的,而是引用侧自带的;
  • 重试发生在业务最脆弱的时刻——下游已经慢了或抖了,你还加流量。
  • @DubboReference 常见默认(以经典版本语义为准,不同小版本请对照官方文档):

    参数常见默认含义
    timeout 1000ms 单次调用超时
    retries 2 额外重试次数(不含第一次)

    也就是说:一次业务调用,最坏情况下会在链路上变成 1 + 2 = 3 次真实请求。

    提供方

    消费方

    提供方

    消费方

    #mermaid-svg-7y1czhdc49cJUf0i{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-7y1czhdc49cJUf0i .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-7y1czhdc49cJUf0i .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-7y1czhdc49cJUf0i .error-icon{fill:#552222;}#mermaid-svg-7y1czhdc49cJUf0i .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-7y1czhdc49cJUf0i .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-7y1czhdc49cJUf0i .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-7y1czhdc49cJUf0i .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-7y1czhdc49cJUf0i .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-7y1czhdc49cJUf0i .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-7y1czhdc49cJUf0i .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-7y1czhdc49cJUf0i .marker{fill:#333333;stroke:#333333;}#mermaid-svg-7y1czhdc49cJUf0i .marker.cross{stroke:#333333;}#mermaid-svg-7y1czhdc49cJUf0i svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-7y1czhdc49cJUf0i p{margin:0;}#mermaid-svg-7y1czhdc49cJUf0i .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-7y1czhdc49cJUf0i text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-7y1czhdc49cJUf0i .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-7y1czhdc49cJUf0i .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-7y1czhdc49cJUf0i .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-7y1czhdc49cJUf0i .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-7y1czhdc49cJUf0i #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-7y1czhdc49cJUf0i .sequenceNumber{fill:white;}#mermaid-svg-7y1czhdc49cJUf0i #sequencenumber{fill:#333;}#mermaid-svg-7y1czhdc49cJUf0i #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-7y1czhdc49cJUf0i .messageText{fill:#333;stroke:none;}#mermaid-svg-7y1czhdc49cJUf0i .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-7y1czhdc49cJUf0i .labelText,#mermaid-svg-7y1czhdc49cJUf0i .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-7y1czhdc49cJUf0i .loopText,#mermaid-svg-7y1czhdc49cJUf0i .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-7y1czhdc49cJUf0i .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-7y1czhdc49cJUf0i .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-7y1czhdc49cJUf0i .noteText,#mermaid-svg-7y1czhdc49cJUf0i .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-7y1czhdc49cJUf0i .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-7y1czhdc49cJUf0i .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-7y1czhdc49cJUf0i .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-7y1czhdc49cJUf0i .actorPopupMenu{position:absolute;}#mermaid-svg-7y1czhdc49cJUf0i .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-7y1czhdc49cJUf0i .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-7y1czhdc49cJUf0i .actor-man circle,#mermaid-svg-7y1czhdc49cJUf0i line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-7y1czhdc49cJUf0i :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    变慢或抖动, 超过 timeout

    第 1 次调用

    超时

    第 2 次 (重试 1)

    仍超时

    第 3 次 (重试 2)

    成功或最终失败

    图:retries=2 时,一次业务意图最多打出三次真实 RPC

    读操作、幂等写,重试常常有价值;非幂等写(下单、扣款、开户、发奖)一旦重复执行,就是脏数据。更隐蔽的是:即便接口碰巧幂等,流量放大本身也能把下游打穿。


    二、问题:放大是怎么算出来的

    笔记里用过这样一个数量级推演(不是压测报告,是说明机制):

    • 某接口稳态大约 100 TPS;
    • 高峰时 RT 爬到约 950ms,仍低于 1000ms 超时,系统「看起来还能转」;
    • 再挤一点,落到 100~120 TPS 区间,部分请求 RT 变成约 1050ms,触发超时。

    于是那多出来的约 20 TPS「刚好超时」的请求,各自再打 2 次重试:额外打出约 40 TPS,合计约 60 TPS 的真实打点落在下游。

    原本只是略超载的尾巴,瞬间变成三倍火力。下游队列更长 → RT 更高 → 更多请求超时 → 更多重试,正反馈成型。

    #mermaid-svg-0r6NbinjaT5HBS6m{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-0r6NbinjaT5HBS6m .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-0r6NbinjaT5HBS6m .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-0r6NbinjaT5HBS6m .error-icon{fill:#552222;}#mermaid-svg-0r6NbinjaT5HBS6m .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0r6NbinjaT5HBS6m .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-0r6NbinjaT5HBS6m .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0r6NbinjaT5HBS6m .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0r6NbinjaT5HBS6m .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-0r6NbinjaT5HBS6m .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0r6NbinjaT5HBS6m .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0r6NbinjaT5HBS6m .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0r6NbinjaT5HBS6m .marker.cross{stroke:#333333;}#mermaid-svg-0r6NbinjaT5HBS6m svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0r6NbinjaT5HBS6m p{margin:0;}#mermaid-svg-0r6NbinjaT5HBS6m .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-0r6NbinjaT5HBS6m .cluster-label text{fill:#333;}#mermaid-svg-0r6NbinjaT5HBS6m .cluster-label span{color:#333;}#mermaid-svg-0r6NbinjaT5HBS6m .cluster-label span p{background-color:transparent;}#mermaid-svg-0r6NbinjaT5HBS6m .label text,#mermaid-svg-0r6NbinjaT5HBS6m span{fill:#333;color:#333;}#mermaid-svg-0r6NbinjaT5HBS6m .node rect,#mermaid-svg-0r6NbinjaT5HBS6m .node circle,#mermaid-svg-0r6NbinjaT5HBS6m .node ellipse,#mermaid-svg-0r6NbinjaT5HBS6m .node polygon,#mermaid-svg-0r6NbinjaT5HBS6m .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0r6NbinjaT5HBS6m .rough-node .label text,#mermaid-svg-0r6NbinjaT5HBS6m .node .label text,#mermaid-svg-0r6NbinjaT5HBS6m .image-shape .label,#mermaid-svg-0r6NbinjaT5HBS6m .icon-shape .label{text-anchor:middle;}#mermaid-svg-0r6NbinjaT5HBS6m .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-0r6NbinjaT5HBS6m .rough-node .label,#mermaid-svg-0r6NbinjaT5HBS6m .node .label,#mermaid-svg-0r6NbinjaT5HBS6m .image-shape .label,#mermaid-svg-0r6NbinjaT5HBS6m .icon-shape .label{text-align:center;}#mermaid-svg-0r6NbinjaT5HBS6m .node.clickable{cursor:pointer;}#mermaid-svg-0r6NbinjaT5HBS6m .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-0r6NbinjaT5HBS6m .arrowheadPath{fill:#333333;}#mermaid-svg-0r6NbinjaT5HBS6m .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0r6NbinjaT5HBS6m .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0r6NbinjaT5HBS6m .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0r6NbinjaT5HBS6m .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-0r6NbinjaT5HBS6m .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0r6NbinjaT5HBS6m .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-0r6NbinjaT5HBS6m .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0r6NbinjaT5HBS6m .cluster text{fill:#333;}#mermaid-svg-0r6NbinjaT5HBS6m .cluster span{color:#333;}#mermaid-svg-0r6NbinjaT5HBS6m div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0r6NbinjaT5HBS6m .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-0r6NbinjaT5HBS6m rect.text{fill:none;stroke-width:0;}#mermaid-svg-0r6NbinjaT5HBS6m .icon-shape,#mermaid-svg-0r6NbinjaT5HBS6m .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-0r6NbinjaT5HBS6m .icon-shape p,#mermaid-svg-0r6NbinjaT5HBS6m .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-0r6NbinjaT5HBS6m .icon-shape .label rect,#mermaid-svg-0r6NbinjaT5HBS6m .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-0r6NbinjaT5HBS6m .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-0r6NbinjaT5HBS6m .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-0r6NbinjaT5HBS6m :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    负载略增

    部分请求 RT 越过 timeout

    消费方自动重试

    下游实际 QPS 被放大

    队列更长 / RT 更高

    同步链路雪崩

    图:超时重试在过载点附近形成正反馈,而不是帮你渡过抖动

    同步 RPC 的强耦合会让这件事更狠:A 调 B,B 调 C,每一跳如果都带着默认重试,放大是乘出来的,不是加出来的。

    #mermaid-svg-6qoPzsIMWfln98Dn{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6qoPzsIMWfln98Dn .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6qoPzsIMWfln98Dn .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6qoPzsIMWfln98Dn .error-icon{fill:#552222;}#mermaid-svg-6qoPzsIMWfln98Dn .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6qoPzsIMWfln98Dn .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6qoPzsIMWfln98Dn .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6qoPzsIMWfln98Dn .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6qoPzsIMWfln98Dn .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6qoPzsIMWfln98Dn .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6qoPzsIMWfln98Dn .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6qoPzsIMWfln98Dn .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6qoPzsIMWfln98Dn .marker.cross{stroke:#333333;}#mermaid-svg-6qoPzsIMWfln98Dn svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6qoPzsIMWfln98Dn p{margin:0;}#mermaid-svg-6qoPzsIMWfln98Dn .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-6qoPzsIMWfln98Dn .cluster-label text{fill:#333;}#mermaid-svg-6qoPzsIMWfln98Dn .cluster-label span{color:#333;}#mermaid-svg-6qoPzsIMWfln98Dn .cluster-label span p{background-color:transparent;}#mermaid-svg-6qoPzsIMWfln98Dn .label text,#mermaid-svg-6qoPzsIMWfln98Dn span{fill:#333;color:#333;}#mermaid-svg-6qoPzsIMWfln98Dn .node rect,#mermaid-svg-6qoPzsIMWfln98Dn .node circle,#mermaid-svg-6qoPzsIMWfln98Dn .node ellipse,#mermaid-svg-6qoPzsIMWfln98Dn .node polygon,#mermaid-svg-6qoPzsIMWfln98Dn .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6qoPzsIMWfln98Dn .rough-node .label text,#mermaid-svg-6qoPzsIMWfln98Dn .node .label text,#mermaid-svg-6qoPzsIMWfln98Dn .image-shape .label,#mermaid-svg-6qoPzsIMWfln98Dn .icon-shape .label{text-anchor:middle;}#mermaid-svg-6qoPzsIMWfln98Dn .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-6qoPzsIMWfln98Dn .rough-node .label,#mermaid-svg-6qoPzsIMWfln98Dn .node .label,#mermaid-svg-6qoPzsIMWfln98Dn .image-shape .label,#mermaid-svg-6qoPzsIMWfln98Dn .icon-shape .label{text-align:center;}#mermaid-svg-6qoPzsIMWfln98Dn .node.clickable{cursor:pointer;}#mermaid-svg-6qoPzsIMWfln98Dn .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-6qoPzsIMWfln98Dn .arrowheadPath{fill:#333333;}#mermaid-svg-6qoPzsIMWfln98Dn .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6qoPzsIMWfln98Dn .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6qoPzsIMWfln98Dn .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6qoPzsIMWfln98Dn .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-6qoPzsIMWfln98Dn .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6qoPzsIMWfln98Dn .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-6qoPzsIMWfln98Dn .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6qoPzsIMWfln98Dn .cluster text{fill:#333;}#mermaid-svg-6qoPzsIMWfln98Dn .cluster span{color:#333;}#mermaid-svg-6qoPzsIMWfln98Dn div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6qoPzsIMWfln98Dn .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-6qoPzsIMWfln98Dn rect.text{fill:none;stroke-width:0;}#mermaid-svg-6qoPzsIMWfln98Dn .icon-shape,#mermaid-svg-6qoPzsIMWfln98Dn .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-6qoPzsIMWfln98Dn .icon-shape p,#mermaid-svg-6qoPzsIMWfln98Dn .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-6qoPzsIMWfln98Dn .icon-shape .label rect,#mermaid-svg-6qoPzsIMWfln98Dn .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-6qoPzsIMWfln98Dn .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-6qoPzsIMWfln98Dn .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-6qoPzsIMWfln98Dn :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    retries=2

    B 调 C 也 retries=2

    业务 1 QPS

    对 B 约 3 QPS

    对 C 约 9 QPS

    图:链路上每跳都默认重试时,放大是相乘的

    和「有意设计的重试」对比:

    类型典型场景是否该自动重试
    查询 / 可幂等读 详情、列表 可以,但要预算
    幂等写 带幂等键的结果通知 可以,仍要限次
    非幂等写 无令牌的扣减、创建 默认不应重试
    参数错误 / 业务拒绝 明确的业务失败 不应重试

    三、方案对比:关掉、改配置,还是换策略

    做法优点代价
    全局 retries=0 放大立刻消失 真抖动时读请求成功率下降
    按接口区分:写 0、读 1~2 精确 要梳理接口清单
    只拉长 timeout 少触发超时 线程占用更久,可能更堵
    超时 + 限流 / 熔断 过载时快速失败 要平台能力与阈值治理
    业务层可重试队列 异步、可观测 改造大,不适合所有链路

    我倾向的默认策略:

    写操作(尤其非幂等)retries=0;读操作允许少量重试,但 timeout 乘以 (1+retries) 必须落在线程池与上游超时预算内。

    #mermaid-svg-AEKgZhltpBhFFaSK{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-AEKgZhltpBhFFaSK .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-AEKgZhltpBhFFaSK .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-AEKgZhltpBhFFaSK .error-icon{fill:#552222;}#mermaid-svg-AEKgZhltpBhFFaSK .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-AEKgZhltpBhFFaSK .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-AEKgZhltpBhFFaSK .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-AEKgZhltpBhFFaSK .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-AEKgZhltpBhFFaSK .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-AEKgZhltpBhFFaSK .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-AEKgZhltpBhFFaSK .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-AEKgZhltpBhFFaSK .marker{fill:#333333;stroke:#333333;}#mermaid-svg-AEKgZhltpBhFFaSK .marker.cross{stroke:#333333;}#mermaid-svg-AEKgZhltpBhFFaSK svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-AEKgZhltpBhFFaSK p{margin:0;}#mermaid-svg-AEKgZhltpBhFFaSK .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-AEKgZhltpBhFFaSK .cluster-label text{fill:#333;}#mermaid-svg-AEKgZhltpBhFFaSK .cluster-label span{color:#333;}#mermaid-svg-AEKgZhltpBhFFaSK .cluster-label span p{background-color:transparent;}#mermaid-svg-AEKgZhltpBhFFaSK .label text,#mermaid-svg-AEKgZhltpBhFFaSK span{fill:#333;color:#333;}#mermaid-svg-AEKgZhltpBhFFaSK .node rect,#mermaid-svg-AEKgZhltpBhFFaSK .node circle,#mermaid-svg-AEKgZhltpBhFFaSK .node ellipse,#mermaid-svg-AEKgZhltpBhFFaSK .node polygon,#mermaid-svg-AEKgZhltpBhFFaSK .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-AEKgZhltpBhFFaSK .rough-node .label text,#mermaid-svg-AEKgZhltpBhFFaSK .node .label text,#mermaid-svg-AEKgZhltpBhFFaSK .image-shape .label,#mermaid-svg-AEKgZhltpBhFFaSK .icon-shape .label{text-anchor:middle;}#mermaid-svg-AEKgZhltpBhFFaSK .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-AEKgZhltpBhFFaSK .rough-node .label,#mermaid-svg-AEKgZhltpBhFFaSK .node .label,#mermaid-svg-AEKgZhltpBhFFaSK .image-shape .label,#mermaid-svg-AEKgZhltpBhFFaSK .icon-shape .label{text-align:center;}#mermaid-svg-AEKgZhltpBhFFaSK .node.clickable{cursor:pointer;}#mermaid-svg-AEKgZhltpBhFFaSK .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-AEKgZhltpBhFFaSK .arrowheadPath{fill:#333333;}#mermaid-svg-AEKgZhltpBhFFaSK .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-AEKgZhltpBhFFaSK .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-AEKgZhltpBhFFaSK .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AEKgZhltpBhFFaSK .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-AEKgZhltpBhFFaSK .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AEKgZhltpBhFFaSK .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-AEKgZhltpBhFFaSK .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-AEKgZhltpBhFFaSK .cluster text{fill:#333;}#mermaid-svg-AEKgZhltpBhFFaSK .cluster span{color:#333;}#mermaid-svg-AEKgZhltpBhFFaSK div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-AEKgZhltpBhFFaSK .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-AEKgZhltpBhFFaSK rect.text{fill:none;stroke-width:0;}#mermaid-svg-AEKgZhltpBhFFaSK .icon-shape,#mermaid-svg-AEKgZhltpBhFFaSK .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-AEKgZhltpBhFFaSK .icon-shape p,#mermaid-svg-AEKgZhltpBhFFaSK .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-AEKgZhltpBhFFaSK .icon-shape .label rect,#mermaid-svg-AEKgZhltpBhFFaSK .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-AEKgZhltpBhFFaSK .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-AEKgZhltpBhFFaSK .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-AEKgZhltpBhFFaSK :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    否

    是

    否

    是

    一次出站调用

    是否幂等?

    retries=0失败走补偿

    允许有限重试

    还在超时预算内?

    先改预算或拆异步

    配置 retries 与退避

    图:先问幂等,再谈重试次数;预算不够就不要用重试硬扛


    四、落地:配置、预算与幂等

    4.1 把默认改成「显式」

    消费方示例(语义示意):

    dubbo:
    consumer:
    timeout: 3000
    retries: 0 # 全局先关掉,再按接口打开
    provider:
    timeout: 3000

    单接口:

    // 非幂等写:禁止重试
    @DubboReference(timeout = 3000, retries = 0)
    private OrderFacade orderFacade;

    // 幂等查询:允许有限重试
    @DubboReference(timeout = 2000, retries = 1)
    private OrderQueryFacade orderQueryFacade;

    提供方也可声明更稳妥的超时,引用侧对个别接口再覆盖;写路径上的 retries 宁可写死 0,也不要依赖「大家记得改」。

    4.2 算清楚「重试预算」

    设上游网关超时为 (T_{up}),单次 RPC 超时为 (t),额外重试次数为 (r),则最坏占用约 (t \\times (1+r)),必须明显小于本层可用时间,否则你会在上游已经 504 之后还在下游空转。

    #mermaid-svg-kj7zW1Q2s37BgNGZ{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-kj7zW1Q2s37BgNGZ .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-kj7zW1Q2s37BgNGZ .error-icon{fill:#552222;}#mermaid-svg-kj7zW1Q2s37BgNGZ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-kj7zW1Q2s37BgNGZ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-kj7zW1Q2s37BgNGZ .marker.cross{stroke:#333333;}#mermaid-svg-kj7zW1Q2s37BgNGZ svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-kj7zW1Q2s37BgNGZ p{margin:0;}#mermaid-svg-kj7zW1Q2s37BgNGZ .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-kj7zW1Q2s37BgNGZ .cluster-label text{fill:#333;}#mermaid-svg-kj7zW1Q2s37BgNGZ .cluster-label span{color:#333;}#mermaid-svg-kj7zW1Q2s37BgNGZ .cluster-label span p{background-color:transparent;}#mermaid-svg-kj7zW1Q2s37BgNGZ .label text,#mermaid-svg-kj7zW1Q2s37BgNGZ span{fill:#333;color:#333;}#mermaid-svg-kj7zW1Q2s37BgNGZ .node rect,#mermaid-svg-kj7zW1Q2s37BgNGZ .node circle,#mermaid-svg-kj7zW1Q2s37BgNGZ .node ellipse,#mermaid-svg-kj7zW1Q2s37BgNGZ .node polygon,#mermaid-svg-kj7zW1Q2s37BgNGZ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-kj7zW1Q2s37BgNGZ .rough-node .label text,#mermaid-svg-kj7zW1Q2s37BgNGZ .node .label text,#mermaid-svg-kj7zW1Q2s37BgNGZ .image-shape .label,#mermaid-svg-kj7zW1Q2s37BgNGZ .icon-shape .label{text-anchor:middle;}#mermaid-svg-kj7zW1Q2s37BgNGZ .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-kj7zW1Q2s37BgNGZ .rough-node .label,#mermaid-svg-kj7zW1Q2s37BgNGZ .node .label,#mermaid-svg-kj7zW1Q2s37BgNGZ .image-shape .label,#mermaid-svg-kj7zW1Q2s37BgNGZ .icon-shape .label{text-align:center;}#mermaid-svg-kj7zW1Q2s37BgNGZ .node.clickable{cursor:pointer;}#mermaid-svg-kj7zW1Q2s37BgNGZ .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-kj7zW1Q2s37BgNGZ .arrowheadPath{fill:#333333;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-kj7zW1Q2s37BgNGZ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kj7zW1Q2s37BgNGZ .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-kj7zW1Q2s37BgNGZ .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kj7zW1Q2s37BgNGZ .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-kj7zW1Q2s37BgNGZ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-kj7zW1Q2s37BgNGZ .cluster text{fill:#333;}#mermaid-svg-kj7zW1Q2s37BgNGZ .cluster span{color:#333;}#mermaid-svg-kj7zW1Q2s37BgNGZ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-kj7zW1Q2s37BgNGZ .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-kj7zW1Q2s37BgNGZ rect.text{fill:none;stroke-width:0;}#mermaid-svg-kj7zW1Q2s37BgNGZ .icon-shape,#mermaid-svg-kj7zW1Q2s37BgNGZ .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-kj7zW1Q2s37BgNGZ .icon-shape p,#mermaid-svg-kj7zW1Q2s37BgNGZ .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-kj7zW1Q2s37BgNGZ .icon-shape .label rect,#mermaid-svg-kj7zW1Q2s37BgNGZ .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-kj7zW1Q2s37BgNGZ .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-kj7zW1Q2s37BgNGZ .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-kj7zW1Q2s37BgNGZ :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    上游超时 3s

    本服务预留 0.5s

    可给下游的预算约 2.5s

    timeout=1.2s retries=1最坏约 2.4s

    timeout=1s retries=2最坏约 3s 超预算

    图:同一预算下,多一次重试可能直接顶穿上游超时

    4.3 和熔断、限流怎么配合

    重试解决的是偶发失败;过载时正确动作是快速失败,而不是更用力地打。过载点附近要减流量,不要加流量。熔断组件的超时、隔离、熔断和 Dubbo retries 是两层事——前者防雪崩,后者若配置不当是在制造雪崩。

    异步场景(@Async、线程池)同样要避免「调用方重试 + 线程池堆积」叠加。

    4.4 业务层:幂等键比「多试两次」更重要

    对必须至少一次成功的写操作:

  • 调用方生成业务幂等号;
  • 提供方以幂等号去重;
  • 失败进入可观测的补偿(本地表 / MQ),而不是同步 RPC 上 retries=2。
  • Spring Retry 等框架适合应用内有策略的重试(指定异常、退避),但原则一样:非幂等不要盲重试。

    #mermaid-svg-Cqs9zmGrY7JMMEJT{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-Cqs9zmGrY7JMMEJT .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-Cqs9zmGrY7JMMEJT .error-icon{fill:#552222;}#mermaid-svg-Cqs9zmGrY7JMMEJT .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Cqs9zmGrY7JMMEJT .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Cqs9zmGrY7JMMEJT .marker.cross{stroke:#333333;}#mermaid-svg-Cqs9zmGrY7JMMEJT svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Cqs9zmGrY7JMMEJT p{margin:0;}#mermaid-svg-Cqs9zmGrY7JMMEJT .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-Cqs9zmGrY7JMMEJT .cluster-label text{fill:#333;}#mermaid-svg-Cqs9zmGrY7JMMEJT .cluster-label span{color:#333;}#mermaid-svg-Cqs9zmGrY7JMMEJT .cluster-label span p{background-color:transparent;}#mermaid-svg-Cqs9zmGrY7JMMEJT .label text,#mermaid-svg-Cqs9zmGrY7JMMEJT span{fill:#333;color:#333;}#mermaid-svg-Cqs9zmGrY7JMMEJT .node rect,#mermaid-svg-Cqs9zmGrY7JMMEJT .node circle,#mermaid-svg-Cqs9zmGrY7JMMEJT .node ellipse,#mermaid-svg-Cqs9zmGrY7JMMEJT .node polygon,#mermaid-svg-Cqs9zmGrY7JMMEJT .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Cqs9zmGrY7JMMEJT .rough-node .label text,#mermaid-svg-Cqs9zmGrY7JMMEJT .node .label text,#mermaid-svg-Cqs9zmGrY7JMMEJT .image-shape .label,#mermaid-svg-Cqs9zmGrY7JMMEJT .icon-shape .label{text-anchor:middle;}#mermaid-svg-Cqs9zmGrY7JMMEJT .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-Cqs9zmGrY7JMMEJT .rough-node .label,#mermaid-svg-Cqs9zmGrY7JMMEJT .node .label,#mermaid-svg-Cqs9zmGrY7JMMEJT .image-shape .label,#mermaid-svg-Cqs9zmGrY7JMMEJT .icon-shape .label{text-align:center;}#mermaid-svg-Cqs9zmGrY7JMMEJT .node.clickable{cursor:pointer;}#mermaid-svg-Cqs9zmGrY7JMMEJT .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-Cqs9zmGrY7JMMEJT .arrowheadPath{fill:#333333;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Cqs9zmGrY7JMMEJT .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Cqs9zmGrY7JMMEJT .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-Cqs9zmGrY7JMMEJT .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Cqs9zmGrY7JMMEJT .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-Cqs9zmGrY7JMMEJT .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Cqs9zmGrY7JMMEJT .cluster text{fill:#333;}#mermaid-svg-Cqs9zmGrY7JMMEJT .cluster span{color:#333;}#mermaid-svg-Cqs9zmGrY7JMMEJT div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Cqs9zmGrY7JMMEJT .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-Cqs9zmGrY7JMMEJT rect.text{fill:none;stroke-width:0;}#mermaid-svg-Cqs9zmGrY7JMMEJT .icon-shape,#mermaid-svg-Cqs9zmGrY7JMMEJT .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-Cqs9zmGrY7JMMEJT .icon-shape p,#mermaid-svg-Cqs9zmGrY7JMMEJT .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-Cqs9zmGrY7JMMEJT .icon-shape .label rect,#mermaid-svg-Cqs9zmGrY7JMMEJT .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-Cqs9zmGrY7JMMEJT .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-Cqs9zmGrY7JMMEJT .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-Cqs9zmGrY7JMMEJT :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    失败类型

    网络抖动 / 超时

    业务拒绝 / 参数错误

    非幂等写已部分成功

    可有限重试 + 退避

    不要重试

    图:框架只能执行策略;策略本身必须按失败类型区分


    五、排查清单:怀疑「被重试放大」时看什么

    #mermaid-svg-43IiaAsnODweA9xr{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-43IiaAsnODweA9xr .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-43IiaAsnODweA9xr .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-43IiaAsnODweA9xr .error-icon{fill:#552222;}#mermaid-svg-43IiaAsnODweA9xr .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-43IiaAsnODweA9xr .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-43IiaAsnODweA9xr .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-43IiaAsnODweA9xr .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-43IiaAsnODweA9xr .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-43IiaAsnODweA9xr .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-43IiaAsnODweA9xr .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-43IiaAsnODweA9xr .marker{fill:#333333;stroke:#333333;}#mermaid-svg-43IiaAsnODweA9xr .marker.cross{stroke:#333333;}#mermaid-svg-43IiaAsnODweA9xr svg{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-43IiaAsnODweA9xr p{margin:0;}#mermaid-svg-43IiaAsnODweA9xr .label{font-family:\”trebuchet ms\”,verdana,arial,sans-serif;color:#333;}#mermaid-svg-43IiaAsnODweA9xr .cluster-label text{fill:#333;}#mermaid-svg-43IiaAsnODweA9xr .cluster-label span{color:#333;}#mermaid-svg-43IiaAsnODweA9xr .cluster-label span p{background-color:transparent;}#mermaid-svg-43IiaAsnODweA9xr .label text,#mermaid-svg-43IiaAsnODweA9xr span{fill:#333;color:#333;}#mermaid-svg-43IiaAsnODweA9xr .node rect,#mermaid-svg-43IiaAsnODweA9xr .node circle,#mermaid-svg-43IiaAsnODweA9xr .node ellipse,#mermaid-svg-43IiaAsnODweA9xr .node polygon,#mermaid-svg-43IiaAsnODweA9xr .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-43IiaAsnODweA9xr .rough-node .label text,#mermaid-svg-43IiaAsnODweA9xr .node .label text,#mermaid-svg-43IiaAsnODweA9xr .image-shape .label,#mermaid-svg-43IiaAsnODweA9xr .icon-shape .label{text-anchor:middle;}#mermaid-svg-43IiaAsnODweA9xr .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-43IiaAsnODweA9xr .rough-node .label,#mermaid-svg-43IiaAsnODweA9xr .node .label,#mermaid-svg-43IiaAsnODweA9xr .image-shape .label,#mermaid-svg-43IiaAsnODweA9xr .icon-shape .label{text-align:center;}#mermaid-svg-43IiaAsnODweA9xr .node.clickable{cursor:pointer;}#mermaid-svg-43IiaAsnODweA9xr .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-43IiaAsnODweA9xr .arrowheadPath{fill:#333333;}#mermaid-svg-43IiaAsnODweA9xr .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-43IiaAsnODweA9xr .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-43IiaAsnODweA9xr .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-43IiaAsnODweA9xr .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-43IiaAsnODweA9xr .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-43IiaAsnODweA9xr .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-43IiaAsnODweA9xr .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-43IiaAsnODweA9xr .cluster text{fill:#333;}#mermaid-svg-43IiaAsnODweA9xr .cluster span{color:#333;}#mermaid-svg-43IiaAsnODweA9xr div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:\”trebuchet ms\”,verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-43IiaAsnODweA9xr .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-43IiaAsnODweA9xr rect.text{fill:none;stroke-width:0;}#mermaid-svg-43IiaAsnODweA9xr .icon-shape,#mermaid-svg-43IiaAsnODweA9xr .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-43IiaAsnODweA9xr .icon-shape p,#mermaid-svg-43IiaAsnODweA9xr .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-43IiaAsnODweA9xr .icon-shape .label rect,#mermaid-svg-43IiaAsnODweA9xr .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-43IiaAsnODweA9xr .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-43IiaAsnODweA9xr .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-43IiaAsnODweA9xr :root{–mermaid-font-family:\”trebuchet ms\”,verdana,arial,sans-serif;}

    是

    否

    下游 RT 或错误率升高

    核对消费方 timeout 与 retries

    对比业务 QPS 与提供方接入 QPS

    接入 QPS 是否接近业务 QPS 乘以 1+retries?

    高度疑似重试放大

    转向慢 SQL / 池耗尽 / GC

    写路径 retries 改 0补幂等与熔断

    图:用「两端 QPS 倍率」验证是不是重试在放大

    实践上再看四点:超时日志是否成簇出现在 RT 刚越过阈值时;写接口是否无幂等键却仍 retries>0;上游网关超时是否小于 timeout × (1+retries);集群容错策略是否与预期一致(Failfast / Failover 等)。


    六、小结

  • Dubbo 引用默认就可能「试三次」——默认值要显式审视。
  • 过载点附近,重试是放大器,不是救生圈。
  • 非幂等写:retries=0;读和幂等写才谈有限重试。
  • 先算超时预算,再填 timeout / retries。
  • 同步重试救不了结构性过载,需要限流、熔断、异步补偿一起上。
  • 赞(0)
    未经允许不得转载:网硕互联帮助中心 » Dubbo 默认超时重试:把下游打雪崩的隐形放大器
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!