Alibaba微服务组件 - Spring Cloud LoadBalancer

1. 什么是Spring Cloud LoadBalance

Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon
Spring官方提供了两种负载均衡的客户端:

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

2. RestTemplate整合LoadBalancer

2.1 引入依赖

<!-- LoadBalancer -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

<!-- 提供了RestTemplate支持 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- nacos服务注册与发现  移除ribbon支持-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </exclusion>
    </exclusions>
</dependency>

注意:

  • nacos-discovery中引入了ribbon,需要移除ribbon的包
  • 如果不移除,也可以在yml中配置不使用ribbon
spring:
  application:
    name: order-server
  cloud:
    nacos:
      server-addr: 127.0.0.1:8848
      discovery:
        username: nacos
        password: macos
        namespace: 6325e312-7f95-48d7-8d06-810047ed3956
    # 不使用ribbon
    loadbalancer:
      ribbon:
        enabled: false

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

2.2 使用@LoadBalanced注解配置RestTemplate

@Configuration
public class RestConfig {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

2.3 使用

package com.xiexie.order.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * @Description
 * @Date 2022-04-07 14:46
 * @Author xie
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private WebClient webClient;

    @Autowired
    private ReactorLoadBalancerExchangeFilterFunction lbFunction;

    @RequestMapping("/add")
    public String add() {
        System.out.println("下单成功");

        //String msg = restTemplate.getForObject("http://localhost:8011/stock/reduct", String.class);

        String msg = restTemplate.getForObject("http://stock-server/stock/reduct", String.class);

        // 基于WebClient
        Mono<String> bodyToMono = webClient.get().uri("http://stock-server/stock/reduct").retrieve().bodyToMono(String.class);

        // 基于WebClient+webFlux
        Mono<String> stringMono = WebClient.builder()
                .filter(lbFunction)
                .build()
                .get()
                .uri("http://stock-server/stock/reduct")
                .retrieve()
                .bodyToMono(String.class);


        return "Hello order add " + msg;
    }

}

3. WebClient整合LoadBalance

3.1 引入依赖

<!-- LoadBalancer -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

<!-- webflux -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>

<!-- nacos服务注册与发现 -->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <exclusions>
        <exclusion>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </exclusion>
    </exclusions>
</dependency>

3.2 配置WebClient作为负载均衡器的client

@Configuration
public class WebClientConfig {

    @LoadBalanced
    @Bean
    WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }

    @Bean
    WebClient webClient() {
      return webClientBuilder().build();
    }
}

3.3 使用(WebClient、WebClient + webFlux)

package com.xiexie.order.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.reactive.ReactorLoadBalancerExchangeFilterFunction;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

/**
 * @Description
 * @Date 2022-04-07 14:46
 * @Author xie
 */
@RestController
@RequestMapping("/order")
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private WebClient webClient;

    @Autowired
    private ReactorLoadBalancerExchangeFilterFunction lbFunction;

    @RequestMapping("/add")
    public String add() {
        System.out.println("下单成功");

        //String msg = restTemplate.getForObject("http://localhost:8011/stock/reduct", String.class);

        String msg = restTemplate.getForObject("http://stock-server/stock/reduct", String.class);

        // 基于WebClient
        Mono<String> bodyToMono = webClient.get().uri("http://stock-server/stock/reduct").retrieve().bodyToMono(String.class);

        // 基于WebClient+webFlux
        Mono<String> stringMono = WebClient.builder()
                .filter(lbFunction)
                .build()
                .get()
                .uri("http://stock-server/stock/reduct")
                .retrieve()
                .bodyToMono(String.class);


        return "Hello order add " + msg;
    }

}

原理: 底层会使用ReactiveLoadBalancer
image

posted @   xiexie0812  阅读(879)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
点击右上角即可分享
微信分享提示