一、核心概念

1. RestTemplate

RestTemplate 是 Spring 提供的用于简化 HTTP 请求的同步客户端工具类,支持 GET、POST、PUT、DELETE 等方法,是微服务间通信的常用方式。

2. Ribbon

Ribbon 是 Netflix 开源的客户端负载均衡器。它可以在客户端实现负载均衡,无需依赖独立的负载均衡设备或服务。

  • 客户端负载均衡:在调用方(消费者)决定请求哪个服务实例。
  • 集成方式:通过 @LoadBalanced 注解修饰 RestTemplate,使其具备服务发现和负载均衡能力。
  • 默认策略:Ribbon 默认使用 轮询(RoundRobinRule) 策略。

3. 常见负载策略

策略名称 类名 说明
轮询策略 RoundRobinRule 按顺序轮流调用服务实例(默认)
随机策略 RandomRule 随机选择一个可用实例
最少并发策略 BestAvailableRule 选择并发请求数最少的实例
响应时间权重策略 WeightedResponseTimeRule 根据响应时间分配权重,响应越快权重越高
重试策略 RetryRule 先轮询,若失败则在指定时间内重试其他实例

二、操作步骤(详细)

步骤 1:添加 Maven 依赖

<dependencies>
    <!-- Spring Boot Web -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <!-- Eureka Client(服务注册与发现) -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
    </dependency>

    <!-- Ribbon 已包含在 eureka-client 中,无需单独引入 -->
    <!-- 若未使用 Eureka,可单独引入 ribbon -->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    </dependency>
</dependencies>

⚠️ 注意:Spring Cloud 2020+ 版本已移除 Ribbon,推荐使用 Spring Cloud LoadBalancer。本文适用于 Spring Cloud Hoxton ~ 2019 版本。

步骤 2:配置 Eureka Server 和服务注册

确保有 Eureka Server,服务提供者已注册,例如:

# application.yml(服务消费者)
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8761/eureka/
spring:
  application:
    name: service-consumer
server:
  port: 8080

步骤 3:创建 RestTemplate 并启用负载均衡

@Configuration
public class RestTemplateConfig {

    @Bean
    @LoadBalanced  // 关键注解:启用 Ribbon 负载均衡
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

步骤 4:使用 RestTemplate 调用服务(服务名代替 IP+端口)

@Service
public class OrderService {

    @Autowired
    private RestTemplate restTemplate;

    public String callUserService() {
        // 使用服务名 "service-provider" 代替具体 IP 和端口
        String url = "http://service-provider/user/1";
        return restTemplate.getForObject(url, String.class);
    }
}

步骤 5:配置 Ribbon 负载均衡策略(轮询 / 随机)

方式一:通过配置文件设置(推荐)

# application.yml
# 针对特定服务配置负载策略
service-provider:  # 服务名(小写)
  ribbon:
    NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule  # 随机策略
    # 或者使用轮询(默认,可不配置)
    # NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RoundRobinRule

✅ 支持的策略类名:

  • 随机:com.netflix.loadbalancer.RandomRule
  • 轮询:com.netflix.loadbalancer.RoundRobinRule

方式二:通过 Java 配置类(自定义配置类)

@Configuration
@RibbonClient(name = "service-provider", configuration = RibbonConfiguration.class)
public class RibbonConfig {
}
// 自定义配置类(避免被 ComponentScan 扫描)
public class RibbonConfiguration {
    @Bean
    public IRule ribbonRule() {
        return new RandomRule(); // 使用随机策略
        // return new RoundRobinRule(); // 轮询策略
    }
}

⚠️ 注意:RibbonConfiguration 类不能被 @ComponentScan 扫到(不要放在主配置类同包或子包),否则会全局影响所有服务。


三、常见错误与解决方案

错误现象 原因 解决方案
UnknownHostException: service-provider 未启用 @LoadBalanced 检查 RestTemplate 是否加了 @LoadBalanced
负载策略未生效 配置类被 @ComponentScan 扫描 将自定义配置类放在独立包中
服务名无法解析 Eureka 未启动或服务未注册 检查 Eureka 控制台,确认服务已注册
ClassNotFoundException: IRule 缺少 Ribbon 依赖 添加 spring-cloud-starter-netflix-ribbon
配置文件策略不生效 YAML 缩进错误或服务名大小写不匹配 服务名必须小写,检查缩进层级

四、注意事项

  1. 服务名大小写敏感:Ribbon 配置中的服务名必须为小写,即使注册中心显示大写。
  2. 配置优先级:Java 配置 > 配置文件 > 默认策略。
  3. Ribbon 已进入维护模式:Spring Cloud 2020+ 推荐使用 Spring Cloud LoadBalancer
  4. 饥饿加载问题:Ribbon 默认懒加载,首次请求慢。可通过配置开启饥饿加载:
ribbon:
  eager-load:
    enabled: true
    clients: service-provider  # 指定服务
  1. 超时与重试配置
service-provider:
  ribbon:
    ConnectTimeout: 3000
    ReadTimeout: 6000
    MaxAutoRetries: 1
    MaxAutoRetriesNextServer: 2

五、使用技巧

  1. 调试负载策略:在服务提供者中打印日志,观察请求是否按预期分发。
  2. 结合 Hystrix 使用:实现熔断 + 负载均衡,提升系统容错性。
  3. 自定义策略:继承 AbstractLoadBalancerRule 实现灰度发布、区域优先等逻辑。
  4. 禁用 Ribbon:若使用 LoadBalancer,可通过配置关闭 Ribbon:
spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: false

六、最佳实践与性能优化

实践 说明
✅ 使用配置文件配置策略 更灵活,无需重新编译
✅ 启用饥饿加载 避免首次调用延迟
✅ 设置合理超时时间 防止线程阻塞
✅ 监控 Ribbon 指标 通过 Actuator 查看负载均衡状态
✅ 避免全局自定义配置 防止影响其他服务
✅ 逐步迁移到 Spring Cloud LoadBalancer 面向未来,支持响应式编程

七、总结

  • RestTemplate + @LoadBalanced + Ribbon 是 Spring Cloud 经典的客户端负载均衡方案。
  • 轮询(RoundRobin)是默认策略,随机(Random)可通过配置轻松切换。
  • 推荐使用 YAML 配置方式 设置策略,简单高效。
  • 注意 Spring Cloud 版本兼容性,新项目建议使用 Spring Cloud LoadBalancer

📌 快速记忆口诀:
一注解,两配置,服务名小写要牢记;轮询默认随机配,Ribbon未来要迁移。