java负载均衡器不负责重试,只负责选健康节点并剔除异常实例;重试由业务层或客户端框架控制,需确保每次重试选择不同节点,配合健康检查与动态恢复实现故障转移。

Java 负载均衡器在并发调用中遇到节点异常时,**不直接负责重试逻辑,而是配合上游调用方协同完成故障转移与有限重试**。它的核心职责是“选节点”,而非“重发请求”。是否重试、重试几次、等多久、重试前是否校验幂等性——这些必须由业务层或客户端框架(如 RestTemplate + Spring Retry、Feign、Resilience4j)控制。负载均衡器只提供异常感知和节点剔除能力,为重试创造可行前提。
识别并隔离异常节点,避免重复分发
当某个服务实例连续失败(如连接超时、SocketException、5xx响应),负载均衡器需及时将其标记为不可用:
- 客户端负载均衡(如 Spring Cloud LoadBalancer 或 Ribbon)依赖健康检查机制:可配置失败阈值(如连续3次失败)+ 半开探测周期,自动从候选列表中临时剔除该节点
- 服务端负载均衡(如 Nginx)通过
max_fails和fail_timeout参数实现类似效果;配合health_check指令主动探活 - 关键点:剔除是临时的、带TTL的,不是永久下线;恢复后需自动回归流量池
支持重试时的节点重选策略
若上层启用了重试(例如 @Retryable 标注的方法),负载均衡器必须确保**每次重试都选择不同节点**,否则重试等于无效循环:
- 轮询类策略(Round Robin)天然支持:下次调用自动落到下一个实例
- 随机类策略(Random)默认满足:每次 selectServer() 都独立采样
- 需规避 IP 哈希、粘性会话等“固定路由”策略——它们会让重试始终打到同一个已宕机节点
- Spring Cloud LoadBalancer 默认启用
RetryAwareServiceInstanceListSupplier,能感知重试上下文,跳过刚失败的实例
与重试机制分工明确,不越界处理
负载均衡器不捕获 TimeoutException 或 IOException 去自行 sleep + 再调用。它只做两件事:
- 在
choose()或selectServer()阶段,返回一个当前认为健康的实例;若无可用节点,则抛出NoAvailableServiceException类异常,交由上层决定是重试、降级还是熔断 - 将节点异常事件(如 ConnectException)上报给注册中心或监控系统,用于动态调整权重或触发告警
- 真正的重试动作(包括退避、计数、日志、幂等校验)必须由调用方封装,例如用 Resilience4j 的 RetryConfig 设置
retryExceptions(SocketTimeoutException.class, ConnectException.class)
生产建议:组合使用更可靠
单一机制无法兜底,推荐分层协作:
- 第一层:负载均衡器实时剔除异常节点(秒级响应)
- 第二层:客户端重试框架对可恢复异常执行 3 次以内指数退避重试(总耗时 ≤ 8 秒)
- 第三层:服务端网关(如 Spring Cloud Gateway)配置 fallback 或限流,防止单点崩溃引发雪崩
- 验证方式:模拟某节点 kill -9,观察日志中重试请求是否均匀分散到其余节点,且失败率收敛
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











