MST

星途 面试题库

面试题:微服务架构下Spring Cloud Gateway智能路由的负载均衡策略与动态路由实现

在Spring Cloud Gateway智能路由中,有哪些常见的负载均衡策略?如何自定义负载均衡策略?另外,如何实现动态路由,使得路由规则能够根据服务注册中心的变化实时更新?
41.1万 热度难度
后端开发微服务架构

知识考点

AI 面试

面试题答案

一键面试

常见负载均衡策略

  1. 轮询(Round Robin):依次将请求分配到各个服务实例上,是一种简单且常用的策略。例如,假设有三个服务实例 A、B、C,请求依次被分配到 A、B、C、A、B、C……
  2. 随机(Random):每次从服务实例列表中随机选择一个实例来处理请求。适用于对请求分配没有特定顺序要求的场景。
  3. 权重(Weighted):根据服务实例的性能、资源等因素为每个实例分配一个权重,权重越高,被选中处理请求的概率越大。比如实例 A 权重为 2,实例 B 权重为 1,那么在多次请求中,A 被选中的概率约为 B 的两倍。
  4. 最少连接数(Least Connections):优先将请求分配到当前连接数最少的服务实例上,适用于处理长连接请求的场景,能使负载更加均衡。

自定义负载均衡策略

  1. 实现 ReactorLoadBalancer 接口:该接口定义了负载均衡的核心逻辑。
import reactor.core.publisher.Mono;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;

public class CustomLoadBalancer implements ReactorLoadBalancer<ServiceInstance> {
    private final String serviceId;
    private final ServiceInstanceListSupplier serviceInstanceListSupplier;

    public CustomLoadBalancer(String serviceId, ServiceInstanceListSupplier serviceInstanceListSupplier) {
        this.serviceId = serviceId;
        this.serviceInstanceListSupplier = serviceInstanceListSupplier;
    }

    @Override
    public Mono<ServiceInstance> choose() {
        return serviceInstanceListSupplier.get()
               .next()
               .map(serviceInstances -> {
                    // 自定义选择逻辑,例如根据实例的某个属性选择
                    return serviceInstances.get(0); 
                });
    }
}
  1. 创建配置类:将自定义的负载均衡器注册到 Spring 容器中。
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;

@Configuration
public class CustomLoadBalancerConfig {

    @Bean
    public CustomLoadBalancer customLoadBalancer(LoadBalancerClientFactory loadBalancerClientFactory) {
        String serviceId = "your - service - id";
        ServiceInstanceListSupplier supplier = loadBalancerClientFactory.getLazyProvider(serviceId, ServiceInstanceListSupplier.class);
        return new CustomLoadBalancer(serviceId, supplier);
    }
}

实现动态路由

  1. 使用服务注册中心:例如 Eureka、Consul 等。Spring Cloud Gateway 可以与这些服务注册中心集成。
    • 引入依赖:以 Eureka 为例,在 pom.xml 中添加 Eureka 客户端依赖。
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring - cloud - starter - netflix - eureka - client</artifactId>
</dependency>
- **配置服务注册**:在 `application.yml` 中配置 Eureka 客户端。
eureka:
  client:
    service - url:
      defaultZone: http://localhost:8761/eureka/
  1. 动态路由配置:通过 DiscoveryClientRouteDefinitionLocator 实现动态路由。
    • 启用发现客户端:在 Spring Boot 主类上添加 @EnableDiscoveryClient 注解。
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class GatewayApplication {
    public static void main(String[] args) {
        SpringApplication.run(GatewayApplication.class, args);
    }
}
- **配置动态路由**:在 `application.yml` 中配置动态路由规则。
spring:
  cloud:
    gateway:
      discovery:
        locator:
          enabled: true
          lower - case - service - id: true

这样,Spring Cloud Gateway 会根据服务注册中心的变化实时更新路由规则。