Spring Cloud的负载均衡是通过Ribbon组件完成的,Ribbon提供了客户端侧的软件负载均衡算法。Spring Cloud中的RestTemplate和Feign客户端底层的负载均衡是通过Ribbon实现的,本章介绍如何在您的应用中实现RestTemplate和Feign的负载均衡用法。
背景信息
Nacos集成了Ribbon的功能,NacosServerList实现了Ribbon提供的com.netflix.loadbalancer.ServerList接口。这个接口是通用的,其它类似的服务发现组件,Eureka、Consul、ZooKeeper也都实现了对应的ServerList接口,例如DomainExtractingServerList、ConsulServerList和ZookeeperServerList等。
实现该接口相当于接入了通用的Spring Cloud负载均衡规范。从Eureka、Consul、ZooKeeper等服务发现方案切换到Spring Cloud Alibaba的服务发现方案,无论是RestTemplate、FeignClient,以及已过时的AsyncRestTemplate,都无需修改任何代码,即可实现负载均衡。
SAE兼容Hystrix,但是前提是客户端需要引入Hystrix的依赖。支持fallback属性,也可以通过Sentinel实现。
在本地开发应用时,可以使用Alibaba Cloud Toolkit插件实现本地应用和部署在SAE中的应用的相互调用,即端云互联,而无需搭建VPN,帮助您提升开发效率。更多信息,请参见使用Cloud Toolkit实现端云互联(IntelliJ IDEA)。
您可以按照本文的内容实现应用的负载均衡,也可以直接下载应用Demo:service-provider和service-consumer。
RestTemplate和Feign的实现方式有所不同,下面将分别介绍如何在您的应用中实现RestTemplate和Feign的负载均衡用法。
RestTemplate
RestTemplate是Spring提供的用于访问REST服务的客户端,提供了多种便捷访问远程HTTP服务的方法,能够大大提高客户端的编写效率。
您需要在您的应用中按照下面的示例修改代码,以便使用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调用。
配合 @EnableFeignClients和 @FeignClient完成负载均衡请求。
使用 @EnableFeignClients开启Feign功能。
@SpringBootApplication @EnableFeignClients // 开启Feign功能。 public class MyApplication { ... }
使用 @FeignClient构造FeignClient。
@FeignClient(name = "service-provider") public interface EchoService { @RequestMapping(value = "/echo/{str}", method = RequestMethod.GET) String echo(@PathVariable("str") String str); }
注入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
和多个servce-provider
启动后,访问service-consumer
提供的URL,确认是否实现了负载均衡。
RestTemplate
多次访问
/echo-rest/rest-test
查看是否转发到不同的实例。Feign
多次访问
/echo-feign/feign-test
查看是否转发到不同的实例。