java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > Spring负载均衡LoadBalancer

Spring负载均衡LoadBalancer使用详解

作者:morris131

这篇文章主要介绍了Spring负载均衡LoadBalancer使用详解,Spring Cloud LoadBalancer是Spring Cloud官方自己提供的客户端负载均衡器, 用来替代Ribbon,Spring官方提供了两种客户端都可以使用loadbalancer,需要的朋友可以参考下

LoadBalancer

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

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

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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文