微服务负载均衡器LoadBalancer实战

本文介绍了SpringCloudLoadBalancer作为客户端负载均衡器,用于替代Ribbon。详细讲解了如何整合RestTemplate和WebClient,并通过示例展示了如何配置和使用。相较于RestTemplate,WebClient支持异步响应,提高并发性能。建议在SpringCloud中采用WebClient作为Http请求客户端。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.什么是Spring Cloud LoadBalancer

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

RestTemplate、WebClient 整合LoadBalancer详细项目请参考:https://gitee.com/tea-Sir/spring-cloud-alibaba.git

1)引入依赖

 <dependencies>
        <!-- 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服务注册与发现 -->
        <!‐‐ 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: mall-user-loadbalancer-demo
  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    # 不使用ribbon
    loadbalancer:
      ribbon:
        enabled: false

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

2)使用@LoadBalanced注解配置RestTemplate

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

3) 使用

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private RestTemplate restTemplate;

    @RequestMapping(value = "/findOrderByUserId/{id}")
    public R findOrderByUserId(@PathVariable("id") Integer id) {

        String url = "http://mall-order/order/findOrderByUserId/"+id;
        //基于RestTemplate
        R result = restTemplate.getForObject(url,R.class);

        return result;
    }
    }

在这里插入图片描述

3.WebClient整合LoadBalancer

1)引入依赖

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

        <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>

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

@Configuration
public class WebClientConfig {

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


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

}

3) 使用

 @Autowired
    private WebClient webClient;

    @RequestMapping(value = "/findOrderByUserId2/{id}")
    public Mono<R> findOrderByUserIdWithWebClient(@PathVariable("id") Integer id) {

        String url = "http://mall-order/order/findOrderByUserId/"+id;
        //基于WebClient
        Mono<R> result = webClient.get().uri(url)
                .retrieve().bodyToMono(R.class);
        return result;
    }

原理: 底层会使用ReactiveLoadBalancer
在这里插入图片描述

引入webFlux

@Autowired
private ReactorLoadBalancerExchangeFilterFunction lbFunction;

@RequestMapping(value = "/findOrderByUserId3/{id}")
public Mono<R> findOrderByUserIdWithWebFlux(@PathVariable("id") Integer id) {

    String url = "http://mall-order/order/findOrderByUserId/"+id;
    //基于WebClient+webFlux
    Mono<R> result = WebClient.builder()
            .filter(lbFunction)
            .build()
            .get()
            .uri(url)
            .retrieve()
            .bodyToMono(R.class);
    return result;
}

在这里插入图片描述

4.RestTemplate和WebClient区别

使用webClient在等待响应的同时不会阻塞正在执行的线程 ;这种异步编程的方式避免了线程阻塞,线程处理完一个请求紧接着可以处理下一个,能够提高系统的吞吐量;而restTemplate 这种方式是阻塞的,会一直占用当前线程资源,直到http返回响应。如果等待的请求发生了堆积,应用程序将创建大量线程,直至耗尽线程池和所有可用内存。同时伴随着频繁的CPU上下文切换,可能导致性能下降。

但是作为上述两种方式的调用者(消费者)而言,其最终获得http响应结果的耗时并未减少。比如浏览器访问上述ProductController 的两个接口时,返回数据的耗时相同。最终获取(消费)数据的地方还会等待。

使用webclient替代restTemplate的好处是可以异步等待http响应,使得线程不需要阻塞;单位时间内有限资源下支持更高的并发量。

总结

1、Spring Cloud官方自己提供的客户端负载均衡器中,建议采用WebClient作为异步响应式Http请求客户端工具。

WebClient发送Http请求支持异步响应,无需阻塞线程,相同条件下支持更高的并发。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值