CAICAIIs opened a new issue, #3179:
URL: https://github.com/apache/dubbo-go/issues/3179

   ### ✅ 验证清单
   
   - [x] 🔍 我已经搜索过 [现有 
Issues](https://github.com/apache/dubbo-go/issues),确信这不是重复问题
   
   ### 🚀 Go 版本
   
   1.24+
   
   ### 📦 Dubbo-go 版本
   
   v3.3.1
   
   ### 🖥️ 服务端配置
   
   _No response_
   
   ### 💻 客户端配置
   
   _No response_
   
   ### 🌐 协议配置
   
   _No response_
   
   ### 📋 注册中心配置
   
   _No response_
   
   ### 💾 操作系统
   
   🍎 macOS
   
   ### 📝 Bug 描述
   
   `cluster/cluster/failback/cluster_invoker.go` 中的重试逻辑使用固定 5 秒间隔,当大量请求同时失败时,会在 
5 秒后同时重试,造成重试风暴。
   比如: 100 并发失败 → 5 秒后 100 个同时重试 → 重试风暴
   **问题代码** (第 106 行):
   ```go
   retryTask := value.(*retryTimerTask)
   if time.Since(retryTask.lastT).Seconds() < 5 {
       break
   }
   ```
   
   ### 🔄 重现步骤
   
   1. 启动 dubbo-go 消费者,使用 failback 集群策略
   2. 模拟 100 个并发请求同时失败
   3. 观察 5 秒后的重试行为
   
   ### ✅ 预期行为
   
   多个失败请求的重试时间分散,避免同时重试
   
   ### ❌ 实际行为
   
   - 所有失败请求固定等待 5 秒后同时重试
   - 100 个并发失败 → 5 秒后 100 个请求同时重试 → 可能再次失败 → 循环
   
   ### 💡 可能的解决方案
   
   Failback 用于"可以延迟但必须成功"的场景,指数退避让"延迟"更可控,避免雪崩。
   
   使用 github.com/cenkalti/backoff/v4 为每个重试任务实现独立的指数退避:
   ```go
   type retryTimerTask struct {
       // ...
       nextBackoff    time.Duration
       backoff        *backoff.ExponentialBackOff
   }
   // 使用动态间隔替代固定 5 秒
   if time.Since(retryTask.lastT) < retryTask.nextBackoff {
       break
   }
   ```
   模拟 100 个任务同时失败,统计首次重试时间分布:
   旧实现 (固定 5s):
   所有 100 个任务在第 5 秒同时重试
   重试时间分散度: 0ms
   新实现 (指数退避 + jitter):
   100 个任务的首次重试分散在 500ms ~ 1500ms 范围内
   重试时间分散度: ~1000ms


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to