1. 简介

1.1 认识Load Balancer(LB)

Spring Cloud LoadBalancer 是 Spring Cloud 官方自己提供的客户端负载均衡器, 用来替代 Ribbon。简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用)

Spring官方提供了两种负载均衡的客户端:

  • RestTemplate:是 Spring 提供的用于访问 Rest 服务的客户端,RestTemplate 提供了多种便捷访问远程 Http 服务的方法,能够大大提高客户端的编写效率。默认情况下,RestTemplate 默认依赖 jdk 的 HTTP 连接工具。
  • WebClient:是从 Spring WebFlux 5.0 版本开始提供的一个非阻塞的基于响应式编程的进行 Http 请求的客户端工具。它的响应式编程的基于 Reactor的。WebClient 中提供了标准 Http 请求方式对应的 get、post、put、delete 等方法,可以用来发起相应的请求。

    1.2 Load Balancer和Ribbon的区别

  • Ribbon 和 loadbalancer 都是 springcloud 的负载均衡组件。
    Ribbon 是 Netflix 开源的基于 HTTP 和 TCP 等协议负载均衡组件,loadBalancer 是 SpringCloud 自己写的,根据服务 id 获取负载均衡器 rpc 地址。
    Ribbon 的使用需要代码里手动调用目标服务,loadBalancer 底层原理是默认调用 Ribbon 的实现客户端负载均衡。

    2. RestTemplate整合LoadBalancer

    2.1 引入依赖

    ```xml

    org.springframework.cloud spring-cloud-starter-loadbalancer
org.springframework.boot spring-boot-starter-web

com.alibaba.cloud spring-cloud-starter-alibaba-nacos-discovery org.springframework.cloud spring-cloud-starter-netflix-ribbon

  1. 如果不移除 ribbon 包,也可以在 yml 中配置不使用 ribbon
  2. ```java
  3. spring:
  4. application:
  5. name: mall-user-loadbalancer-demo
  6. cloud:
  7. nacos:
  8. discovery:
  9. server-addr: 127.0.0.1:8848
  10. # 不使用ribbon
  11. loadbalancer:
  12. ribbon:
  13. enabled: false

原理:默认情况下,如果同时拥有 RibbonLoadBalancerClient 和 BlockingLoadBalancerClient,为了保持向后兼容性,将使用RibbonLoadBalancerClient。要覆盖它,可以设置 spring.cloud.loadbalancer.ribbon.enabled 属性为false。
负载均衡器Load Balancer - 图1

2.2 配置RestTemplate

  1. @Configuration
  2. public class RestConfig {
  3. @Bean
  4. @LoadBalanced
  5. public RestTemplate restTemplate() {
  6. return new RestTemplate();
  7. }
  8. }

2.3 使用RestTemplate

  1. @RestController
  2. @RequestMapping("/user")
  3. public class UserController {
  4. @Autowired
  5. private RestTemplate restTemplate;
  6. @RequestMapping(value = "/findOrderByUserId/{id}")
  7. public R findOrderByUserId(@PathVariable("id") Integer id) {
  8. String url = "http://mall-order/order/findOrderByUserId/"+id;
  9. R result = restTemplate.getForObject(url,R.class);
  10. return result;
  11. }
  12. }

原理: 底层会使用 ReactiveLoadBalancer。
负载均衡器Load Balancer - 图2

2.4 使用WebClient

  1. @Autowired
  2. private ReactorLoadBalancerExchangeFilterFunction lbFunction;
  3. @RequestMapping(value = "/findOrderByUserId3/{id}")
  4. public Mono<R> findOrderByUserIdWithWebFlux(@PathVariable("id") Integer id) {
  5. String url = "http://mall-order/order/findOrderByUserId/"+id;
  6. //基于WebClient+webFlux
  7. Mono<R> result = WebClient.builder()
  8. .filter(lbFunction)
  9. .build()
  10. .get()
  11. .uri(url)
  12. .retrieve()
  13. .bodyToMono(R.class);
  14. return result;
  15. }