面试题答案
一键面试常见负载均衡策略
- 轮询(Round Robin):依次将请求分配到各个服务实例上,是一种简单且常用的策略。例如,假设有三个服务实例 A、B、C,请求依次被分配到 A、B、C、A、B、C……
- 随机(Random):每次从服务实例列表中随机选择一个实例来处理请求。适用于对请求分配没有特定顺序要求的场景。
- 权重(Weighted):根据服务实例的性能、资源等因素为每个实例分配一个权重,权重越高,被选中处理请求的概率越大。比如实例 A 权重为 2,实例 B 权重为 1,那么在多次请求中,A 被选中的概率约为 B 的两倍。
- 最少连接数(Least Connections):优先将请求分配到当前连接数最少的服务实例上,适用于处理长连接请求的场景,能使负载更加均衡。
自定义负载均衡策略
- 实现
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);
});
}
}
- 创建配置类:将自定义的负载均衡器注册到 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);
}
}
实现动态路由
- 使用服务注册中心:例如 Eureka、Consul 等。Spring Cloud Gateway 可以与这些服务注册中心集成。
- 引入依赖:以 Eureka 为例,在
pom.xml
中添加 Eureka 客户端依赖。
- 引入依赖:以 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/
- 动态路由配置:通过
DiscoveryClientRouteDefinitionLocator
实现动态路由。- 启用发现客户端:在 Spring Boot 主类上添加
@EnableDiscoveryClient
注解。
- 启用发现客户端:在 Spring Boot 主类上添加
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 会根据服务注册中心的变化实时更新路由规则。