Spring Cloud LoadBalancer

Spring Cloud LoadBalancer是由SpringCloud官方提供的一个开源的、简单易用的客户端负载均衡器, 它包含在SpringCloud-commons中用它来替换了以前的Ribbon组件。 相比较于RibbonSpring Cloud LoadBalancer不仅能够支持RestTemplate,还支持WebClientWeClientSpring Web Flux中提供的功能,可以实现响应式异步请求)

官网:https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html

Nginx的区别

  • Nginx是服务器负载均衡,客户端所有请求都会交给Nginx,然后由Nginx实现转发请求,即负载均衡是由服务端实现的。
  • loadbalancer本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。

负载均衡算法也是常见的:轮询、随机、最小活跃数、源地址哈希、一致性哈希。

配置使用

如果是Hoxton之前的版本,默认负载均衡器为Ribbon,需要移除Ribbon引用和增加配置

对应版本:

Spring Cloud Alibaba Spring cloud Spring Boot
2.2.6.RELEASE Spring Cloud Hoxton.SR9 2.3.2.RELEASE

如果不移除,也可以在yml中配置不使用Ribbon

spring:
  cloud:
    loadbalancer:
      ribbon:
        enabled: false

移除Ribbon依赖,增加loadBalance依赖

<dependencies>
    <!--nacos-->
    <dependency>
        <groupId>com.alibaba.cloud</groupId>
        <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
        <exclusions>
            <!--排除ribbon-->
            <exclusion>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
            </exclusion>
        </exclusions>
    </dependency>

    <!--添加loadbalanncer依赖, 添加spring-cloud的依赖-->
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-loadbalancer</artifactId>
    </dependency>
</dependencies>

默认情况下,如果同时拥有RibbonLoadBalancerClientBlockingLoadBalancerClient,为了保持兼容性,将使用RibbonLoadBalancerClient

配置文件的参数也调整了:https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html#configuring-individual-loadbalancerclients

spring:
  cloud:
    loadbalancer:
      health-check:
        initial-delay: 1s
      clients:
        myclient:
          health-check:
            interval: 30s

自定义负载均衡器

自定义随机负载均衡器

public class CustomRandomLoadBalancerClient implements ReactorServiceInstanceLoadBalancer {

    // 服务列表
    private ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider;

    public CustomRandomLoadBalancerClient(ObjectProvider<ServiceInstanceListSupplier> serviceInstanceListSupplierProvider) {
        this.serviceInstanceListSupplierProvider = serviceInstanceListSupplierProvider;
    }

    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        ServiceInstanceListSupplier supplier = serviceInstanceListSupplierProvider.getIfAvailable();
        return supplier.get().next().map(this::getInstanceResponse);
    }

    /**
     * 使用随机数获取服务
     * @param instances
     * @return
     */
    private Response<ServiceInstance> getInstanceResponse(List<ServiceInstance> instances) {
        if (instances.isEmpty()) {
            return new EmptyResponse();
        }
        // 随机算法
        int size = instances.size();
        Random random = new Random();
        ServiceInstance instance = instances.get(random.nextInt(size));
        return new DefaultResponse(instance);
    }
}

配置使用

// 设置全局负载均衡器
@LoadBalancerClients(defaultConfiguration = {CustomRandomLoadBalancerClient.class})
// 指定具体服务用某个负载均衡
//@LoadBalancerClient(name = "test",configuration = CustomRandomLoadBalancerClient.class)
//@LoadBalancerClients(
//        value = {
//                @LoadBalancerClient(value = "test",configuration = CustomRandomLoadBalancerClient.class)
//        },defaultConfiguration = LoadBalancerClientConfiguration.class
//)
public class TestConfiguration {
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }
}

这里说下@LoadBalanced注解的使用:它是与@Bean一起作用在RestTemplate上的

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

是为了实现,在注入RestTemplate对象到Spring IoC容器的同时,启用Spring的负载均衡机制。

@LoadBalanced注解的原理

LoadBalancerAutoConfiguration初始化的过程中,创建拦截器LoadBalancerInterceptor,对请求进行拦截从而实现负载均衡。

LoadBalancerInterceptor拦截器在执行请求前调用其intercept方法,intercept负责负载均衡的实现

重试机制

spring:
  cloud:
    loadbalancer:
      clients:
        # default 表示去全局配置,如要针对某个服务,写对应的服务名称
        default:
          retry:
            enbled: true
            # 是否有的的请求都重试,false表示只有GET请求才重试
            retryOnAllOperation: true
            # 同一个实例的重试次数,不包括第一次调用:比如第填写3 ,实际会调用4次
            maxRetriesOnSameServiceInstance: 3
            # 其他实例的重试次数,多节点情况下使用
            maxRetriesOnNextServiceInstance: 0

results matching ""

    No results matching ""