✅ 一、核心概念速记
概念 | 说明 |
---|---|
RestTemplate | Spring 提供的同步 HTTP 客户端,用于调用 RESTful 接口 |
Ribbon | Netflix 提供的客户端负载均衡器,已逐步被 Spring Cloud LoadBalancer 替代 |
@LoadBalanced |
注解开启 RestTemplate 的负载均衡能力,自动集成 Ribbon 或 LoadBalancer |
服务名调用 | 无需写死 IP 和端口,通过服务名(如 user-service )动态发现实例 |
✅ 二、操作步骤(详细)
👉 步骤1:添加依赖(Spring Cloud 2021.x 及以下)
<!-- Eureka 客户端 + Ribbon(旧版) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- Ribbon(仅旧版需要) -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
</dependency>
⚠️ 如果你使用的是 Spring Cloud 2022.x+,Ribbon 已被移除,需使用
spring-cloud-starter-loadbalancer
。
👉 步骤2:配置 RestTemplate(开启负载均衡)
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced // 关键注解:开启负载均衡
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@LoadBalanced
会自动注入LoadBalancerInterceptor
,实现服务名到实例的转换。
👉 步骤3:配置文件(application.yml)
spring:
application:
name: consumer-service
eureka:
client:
service-url:
defaultZone: http://localhost:8761/eureka/
fetch-registry: true
register-with-eureka: true
👉 步骤4:服务调用(使用服务名)
@RestController
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/call")
public String callProvider() {
return restTemplate.getForObject("http://provider-service/hello", String.class);
}
}
注意:
provider-service
是注册到 Eureka 的服务名,不是 IP 或端口。
👉 步骤5:启动测试
- 启动 Eureka Server(端口8761)
- 启动 provider-service 多实例(如 8081、8082)
- 启动 consumer-service
- 访问:http://localhost:8080/call
多次刷新,请求会轮询到不同实例。
✅ 三、常见错误与排查
错误提示 | 原因 | 解决方案 |
---|---|---|
LoadBalancerClient not found |
缺少 spring-cloud-starter-loadbalancer (2022.x+) |
添加依赖并替换 Ribbon |
UnknownHostException: provider-service |
未加 @LoadBalanced 或服务未注册 |
检查注解、Eureka注册状态 |
负载均衡不生效 | 使用 IP 调用而非服务名 | 改为 http://provider-service/path |
调用超时 | Ribbon 默认超时为1秒 | 配置超时时间(见下方优化) |
✅ 四、注意事项
- 服务名必须唯一,避免大小写敏感问题
- RestTemplate 必须为单例,否则负载均衡器无法复用
- 避免硬编码 IP,否则负载均衡失效
- 测试环境可关闭 Eureka 的自我保护模式,避免误判下线
✅ 五、使用技巧与最佳实践
技巧类别 | 实践建议 |
---|---|
负载均衡策略 | 默认为轮询,可改为随机、权重等 |
动态配置策略 | 在 application.yml 中配置:provider-service.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule |
日志调试 | 开启 Ribbon 日志:logging.level.org.springframework.cloud.netflix.ribbon=DEBUG |
连接池优化 | 使用 HttpComponentsClientHttpRequestFactory 替换默认实现 |
服务降级 | 可集成 Hystrix 或 Sentinel 实现 fallback 逻辑 |
✅ 六、性能优化建议
配置项 | 建议值 | 说明 |
---|---|---|
ribbon.ReadTimeout |
3000ms | 避免网络延迟导致超时 |
ribbon.ConnectTimeout |
1000ms | 快速失败,避免阻塞 |
ribbon.MaxAutoRetriesNextServer |
1 | 失败时尝试下一个实例 |
ribbon.OkToRetryOnAllOperations |
true | 允许重试非幂等请求(谨慎使用) |
ribbon.eager-load.enabled |
true | 启动时预加载,避免首次调用延迟 |
配置示例:
provider-service:
ribbon:
ReadTimeout: 3000
ConnectTimeout: 1000
MaxAutoRetriesNextServer: 1
OkToRetryOnAllOperations: true
✅ 七、一句话总结
RestTemplate + Ribbon = 服务名调用 + @LoadBalanced + Eureka注册中心 + 负载均衡策略