Spring负载均衡LoadBalancer使用详解

 更新时间:2023年11月18日 08:55:43   作者:morris131  
这篇文章主要介绍了Spring负载均衡LoadBalancer使用详解,Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon,Spring官方提供了两种客户端都可以使用loadbalancer,需要的朋友可以参考下

LoadBalancer

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

Spring官方提供了两种客户端都可以使用loadbalancer:

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

RestTemplate整合LoadBalancer

引入LoadBalancer的依赖

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

默认情况下,如果同时拥有RibbonLoadBalancerClient和BlockingLoadBalancerClient,为了保持向后兼容性,将使用RibbonLoadBalancerClient。

要覆盖它,可以设置spring.cloud.loadbalancer.ribbon.enabled属性为false。

spring:
  application:
    name: user-service

  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    # 不使用ribbon,使用loadbalancer
    loadbalancer:
      ribbon:
        enabled: false

使用@LoadBalanced注解修饰RestTemplate,开启客户端负载均衡功能

package com.morris.user.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class RestConfig {

    /**
     * 默认的RestTemplate,不带负载均衡
     * @return
     */
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

    /**
     * 有负责均衡能力的RestTemplate
     * @return
     */
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate2() {
        return new RestTemplate();
    }
}

RestTemplate的使用:

package com.morris.user.controller;

import com.morris.user.entity.Order;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("user")
public class RestTemplateController {

    @Resource
    private RestTemplate restTemplate;

    @Resource
    private RestTemplate restTemplate2;

    @GetMapping("findOrderByUserId")
    public List<Order> findOrderByUserId(Long userId) {
        Order[] orders = restTemplate.getForObject("http://127.0.0.1:8020/order/findOrderByUserId?userId=", Order[].class, userId);
        return Arrays.asList(orders);
    }

    @GetMapping("findOrderByUserId2")
    public List<Order> findOrderByUserId2(Long userId) {
        Order[] orders = restTemplate2.getForObject("http://order-service/order/findOrderByUserId?userId=", Order[].class, userId);
        return Arrays.asList(orders);
    }
}

WebClient整合LoadBalancer

引入依赖webflux,WebClient位于webflux内:

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

同样需要在配置文件中禁用ribbon:

spring:
  application:
    name: user-service

  cloud:
    nacos:
      discovery:
        server-addr: 127.0.0.1:8848
    # 不使用ribbon,使用loadbalancer
    loadbalancer:
      ribbon:
        enabled: false

使用@LoadBalanced注解修饰WebClient.Builder,开启客户端负载均衡功能

package com.morris.user.config;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;

@Configuration
public class WebClientConfig {

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

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

}

WebClient负载均衡的使用:

package com.morris.user.controller;

import com.morris.user.entity.Order;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;

@RestController
@RequestMapping("user2")
public class WebClientController {

    @Resource
    private WebClient.Builder webClientBuilder;

    @Resource
    private WebClient.Builder webClientBuilder2;


    @GetMapping("findOrderByUserId1")
    public Mono<List<Order>> findOrderByUserId1(Long userId) {
        return webClientBuilder.build().get().uri("http://127.0.0.1:8020/order/findOrderByUserId?userId=" + userId)
                .retrieve().bodyToMono(Order[].class).map(t -> Arrays.asList(t));
    }

    @GetMapping("findOrderByUserId2")
    public Mono<List<Order>> findOrderByUserId2(Long userId) {
        return webClientBuilder2.build().get().uri("http://order-service/order/findOrderByUserId?userId=" + userId)
                .retrieve().bodyToMono(Order[].class).map(t -> Arrays.asList(t));
    }

}

原理:底层会使用ReactiveLoadBalancer

WebClient设置Filter实现负载均衡

与RestTemplate类似,@LoadBalanced注解的功能是通过SmartInitializingSingleton实现的。

SmartInitializingSingleton是在所有的bean都实例化完成之后才会调用的,所以在bean的实例化期间使用@LoadBalanced修饰的WebClient是不具备负载均衡作用的,比如在项目的启动过程中要使用调用某个微服务,此时WebClient是不具备负载均衡作用的。

可以通过手动为WebClient设置Filter实现负载均衡能力。

@Bean
WebClient.Builder webClientBuilder3(ReactorLoadBalancerExchangeFilterFunction lbFunction) {
    return WebClient.builder().filter(lbFunction);
}

到此这篇关于Spring负载均衡LoadBalancer使用详解的文章就介绍到这了,更多相关Spring负载均衡LoadBalancer内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java 线程相关总结

    Java 线程相关总结

    这篇文章主要介绍了Java 线程的相关资料,帮助大家更好的理解和学习使用Java,感兴趣的朋友可以了解下
    2021-02-02
  • 详解Mybatis-plus(MP)中CRUD操作保姆级笔记

    详解Mybatis-plus(MP)中CRUD操作保姆级笔记

    本文主要介绍了Mybatis-plus(MP)中CRUD操作保姆级笔记,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-11-11
  • 如何构建可重复读取inputStream的request

    如何构建可重复读取inputStream的request

    这篇文章主要介绍了如何构建可重复读取inputStream的request,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-03-03
  • SpringBoot深入理解之内置web容器及配置的总结

    SpringBoot深入理解之内置web容器及配置的总结

    今天小编就为大家分享一篇关于SpringBoot深入理解之内置web容器及配置的总结,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-03-03
  • Java使用正则表达式验证手机号和电话号码的方法

    Java使用正则表达式验证手机号和电话号码的方法

    今天小编就为大家分享一篇关于Java使用正则表达式验证手机号和电话号码的方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • 详解Http协议以及post与get区别

    详解Http协议以及post与get区别

    这篇文章主要介绍了详解Http协议以及post与get区别,通过分别说明Http协议以及get与post各自的概念,再到两者作比较有着详细的说明,希望对你有所帮助
    2021-06-06
  • springboot整合redisson实现延时队列(附仓库地址)

    springboot整合redisson实现延时队列(附仓库地址)

    延时队列用于管理需要定时执行的任务,对于大数据量和高实时性需求,使用延时队列比定时扫库更高效,Redisson提供一种高效的延时队列实现方式,本文就来详细的介绍一下,感兴趣都可以了解学习
    2024-10-10
  • Nacos 版本不一致报错Request nacos server failed解决

    Nacos 版本不一致报错Request nacos server failed解决

    这篇文章主要为大家介绍了Nacos 版本不一致报错Request nacos server failed的解决方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Java网络编程TCP实现文件上传功能

    Java网络编程TCP实现文件上传功能

    这篇文章主要为大家详细介绍了Java网络编程TCP实现文件上传功能,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-07-07
  • Java基础之FastJson详解

    Java基础之FastJson详解

    今天给大家复习Java基础FastJson,文中有非常详细的代码示例,对正在学习java的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05

最新评论