前言
一般情况下我们所说的负载均衡通常都是指服务端负载均衡,负载均衡器会维护一个可用的后端服务器清单,然后通过心跳机制来删除故障的服务端节点以保证清单中都是可以正常访问的服务端节点,此时当客户端的请求到达负载均衡服务器时,负载均衡器按照某种配置好的规则从可用服务端清单中选出一台服务器去处理客户端的请求。
客户端负载均衡和服务端负载均衡最大的区别在于服务清单所存储的位置。在客户端负载均衡中,所有的客户端节点都有一份自己要访问的服务端清单,这些清单统统都是从Eureka服务注册中心获取的。在Spring Cloud中我们如果想要使用客户端负载均衡,方法很简单,开启@LoadBalanced注解即可,这样客户端在发起请求的时候会先自行选择一个服务端,向该服务端发起请求,从而实现负载均衡。
SpringCloud原有的客户端负载均衡方案Ribbon已经被废弃,取而代之的是SpringCloud LoadBalancer。
相比较于Ribbon,Spring Cloud LoadBalancer不仅能够支持RestTemplate,还支持WebClient。WeClient是Spring Web Flux中提供的功能,可以实现响应式异步请求,因此学习Spring Cloud LoadBalancer之前,建议先了解下Spring Web Flux。
Spring Cloud LoadBalancer 整合RestTemplate的用法和Ribbon是一样的,这里就不再赘述,有必要提一下的就是,如何来更改其负载均衡策略
可以新增配置类,修改其默认的负载均衡策略(轮询算法)
@Configuration public class MyLoadBalancerConfig { @Bean public ReactorServiceInstanceLoadBalancer reactorServiceInstanceLoadBalancer(Environment environment, LoadBalancerClientFactory loadBalancerClientFactory) { String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME); //返回随机轮询负载均衡方式 return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name); } }
并在启动类声明如下注解
@SpringBootApplication @LoadBalancerClient(name = "service-product", configuration = MyLoadBalancerConfig.class)
Spring Cloud LoadBalancer(WebClient)
依赖
<dependency> <!-- Spring Cloud loadbalancer 负载均衡--> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-loadbalancer</artifactId> </dependency> <dependency> <!-- Spring Webflux响应式web编程--> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-webflux</artifactId> </dependency>
Spring Cloud提供了@LoadBalanced注解配合RestTemplate使用Spring Cloud Ribbon实现了客户端的负载均衡。对于Spring Cloud LoadBalancer也可以使用相同的方式。另外Spring Cloud LoadBalancer也提供了接合Spring Web Flux的负载均衡,如果你客户端使用Spring Web Flux完成服务端的访问,也只需相似的配置就能实现客户端负载均衡。
如果在项目的类路径下存在Spring Cloud Ribbon相关的类,需要通过配置关闭Ribbon功能,因为Spring Cloud默认优先使用Ribbon:
(版本稍高的,已经移除了ribbon,可不必关闭)
spring: cloud: loadbalancer: ribbon: enabled: false
WebClient是Spring Web Flux中提供的类,通过使用WebClient可以通过响应式编程的方式异步访问服务端接口。
WebClient.Bulider是WebClient的内部类,也是编程的入口。
编写配置,创建WebClient.Bulider类型的Bean
同样需要在方法上标注@LoadBalanced注解
@Configuration public class LoadbalanceConfiguration { @Bean @LoadBalanced public WebClient.Builder builder() { return WebClient.builder(); } }
编写Controller,客户端实现访问服务端资源,并对外提供访问接口
@RestController @RequestMapping("/rx/client") public class ReactiveClient { private static final String BASE_URL = "http://myServer"; @Autowired private WebClient.Builder clientBuilder; @GetMapping("/getString") public Mono<String> getServerString() { return clientBuilder.baseUrl(BASE_URL).build().get().uri("/base/string").retrieve().bodyToMono(String.class); } }