Spring Cloud 的负载均衡是通过 Ribbon 组件完成的。 Ribbon 主要提供客户侧的软件负载均衡算法。Spring Cloud 中的 RestTemplate 和 Feign 客户端底层的负载均衡都是通过 Ribbon 实现的,本章介绍如何在您的应用中实现 RestTemplate 和 Feign 的负载均衡用法。

背景信息

Spring Cloud AliCloud Ans 集成了 Ribbon 的功能,AnsServerList 实现了 Ribbon 提供的 com.netflix.loadbalancer.ServerList 接口。

这个接口是通用的,其它类似的服务发现组件例如 Nacos、Eureka、Consul、ZooKeeper 也都实现了对应的 ServerList 接口,例如 NacosServerList、 DomainExtractingServerList、ConsulServerList、ZookeeperServerList 等。

实现该接口相当于接入了 Spring Cloud 负载均衡规范,这个规范是共用的。这也意味着,从 Eureka、Consul、ZooKeeper 等服务发现方案切换到 Spring Cloud Alibaba 方案,在负载均衡这个层面,无需修改任何代码,RestTemplate、FeignClient,包括已过时的 AsyncRestTemplate ,都是如此。

操作步骤

RestTemplate 和 Feign 的实现方式有所不同。
  • RestTemplate
    RestTemplate 是 Spring 提供的用于访问 REST 服务的客户端,提供了多种便捷访问远程 HTTP 服务的方法,能够大大提高客户端的编写效率。
    说明

    本文仅提供实现 RestTemplate 和 Feign 的负载均衡代主要代码的造方法,如果您想了解完整的 Spring Cloud 程序,可下载 service-providerservice-consumer

    您需要在您的应用中按照下面的示例修改代码,以便使用 RestTemplate 的负载均衡。
    public class MyApp {
        // 注入刚刚使用 @LoadBalanced 注解修饰构造的 RestTemplate
        // 该注解相当于给 RestTemplate 加上了一个拦截器:LoadBalancerInterceptor
        // LoadBalancerInterceptor 内部会使用 LoadBalancerClient 接口的实现类 RibbonLoadBalancerClient 完成负载均衡
        @Autowired
        private RestTemplate restTemplate;
    ​
        @LoadBalanced // 使用 @LoadBalanced 注解修改构造的 RestTemplate,使其拥有一个负载均衡功能
        @Bean
        public RestTemplate restTemplate() {
            return new RestTemplate();
        }
    
        // 使用 RestTemplate 调用服务,内部会使用负载均衡调用服务
        public void doSomething() {
            Foo foo = restTemplate.getForObject("http://service-provider/query", Foo.class);
            doWithFoo(foo);
        }
    
        ...
    }
    							
  • Feign
    Feign 是 Java 实现的 HTTP 客户端,用于简化 RESTful 调用。
    1. 要想在 Feign 上使用负载均衡,需要添加 Ribbon 的依赖。
      <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
       <version>{version}</version>
      </dependency>
      									
    2. 配合 @EnableFeignClients 和 @FeignClient 完成负载均衡请求。
      1. 使用 @EnableFeignClients 开启 Feign 功能。
        @SpringBootApplication
        @EnableFeignClients // 开启 Feign 功能
        public class MyApplication {
        ...
        }
        											
      2. 使用 @FeignClient 构造 FeignClient。
        @FeignClient(name = "service-provider")
        public interface EchoService {
         @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET)
         String echo(@PathVariable("str") String str);
        }
        											
      3. 注入 EchoService 并完成 echo 方法的调用。
        调用 echo 方法相当于发起了一个 HTTP 请求。
        public class MyService {
           @Autowired // 注入刚刚使用 @FeignClient 注解修饰构造的 EchoService
        private EchoService echoService;
        
        public void doSomething() {
               // 相当于发起了一个 http://service-provider/echo/test 请求
               echoService.echo("test");
           }
        ...
        }
        												

结果验证

service-consumer和多个serveice-provider启动后,访问service-consumer提供的 URL 确认是否实现了负载均衡。
  • RestTemplate

    多次访问/echo-rest/rest-test查看是否转发到不同的实例。

  • Feign

    多次访问/echo-feign/feign-test查看是否转发到不同的实例。