# 03.微服务-负载均衡

Spring Cloud LoadBalancer 是 Spring 官方推出的客户端负载均衡器,已替代 Netflix Ribbon 成为 Spring Cloud 默认负载均衡方案

# 1.负载均衡策略

# 1.1 内置策略

策略名称 实现类 核心原理 适用场景
轮询 RoundRobinLoadBalancer 按顺序轮流选择实例,通过原子计数器取模实现 通用场景,服务实例性能相近
随机 RandomLoadBalancer 从可用实例列表中随机选择 打散请求,避免"热点"实例

# 1.2 通过 ServiceInstanceListSupplier 实现的高级策略

ServiceInstanceListSupplier 是实例列表供应器,可通过链式组合实现高级负载均衡特性

策略类型 核心机制 适用场景
加权 从实例元数据读取 weight 值作为权重,权重越高被选中概率越大;未配置则默认为 1 实例配置异构,希望按比例分配流量
区域感知 优先选择与服务调用方同一区域的实例;同区域无可用实例则回退到全部实例 多机房/跨地域部署,降低网络延迟
健康检查 定期对实例执行健康检查,仅返回健康实例;无健康实例时返回全部 使用 SimpleDiscoveryClient 或无健康检查机制的场景
缓存 缓存实例列表,减少每次请求都拉取注册中心的开销 生产环境必开,大大提升性能

# 1.3 策略对比

对比维度 轮询 (RoundRobin) 随机 (Random) 加权 (Weighted) 区域感知 (ZonePreference)
实现复杂度
负载均衡效果 均匀 近似均匀 按权重不平均 优先同区域
是否需元数据配置 是(需 weight 标签) 是(需 zone 标签)
适用场景 通用 打散请求 异构实例 多机房部署

# 2.配置方式

# 2.1关键配置项

spring:
  cloud:
    loadbalancer:
      # 缓存配置(生产环境推荐)
      cache:
        enabled: true               # 开启缓存,默认 true
        ttl: 35s                    # 缓存过期时间,默认 35s
        capacity: 256               # 缓存初始容量,默认 256

      # 预加载配置(避免首次请求延迟)
      eager-load:
        clients:                    # 指定服务 ID 列表
          - service-a
          - service-b

      # 健康检查配置
      health-check:
        path:
          default: /actuator/health # 健康检查默认路径
        interval: 30s               # 检查间隔

      # 区域配置(区域感知时需要)
      zone: cn-north-1              # 覆盖 DiscoveryClient 的区域设置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 2.2策略配置方式

random配置

public class CustomLoadBalancerConfiguration {

    @Bean
    ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
                                                            LoadBalancerClientFactory loadBalancerClientFactory) {
        String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
        return new RandomLoadBalancer(loadBalancerClientFactory
                .getLazyProvider(name, ServiceInstanceListSupplier.class),
                name);
    }
}
1
2
3
4
5
6
7
8
9
10
11

weight配置

public class WeightedConfig {

    @Bean
    public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
            ConfigurableApplicationContext context) {
        return ServiceInstanceListSupplier.builder()
                .withDiscoveryClient()    // 从注册中心获取实例
                .withWeighted()           // 启用加权(可自定义权重算法)
                .withCaching()            // 启用缓存
                .build(context);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

zone配置

public class ZonePreferenceConfig {

    @Bean
    public ServiceInstanceListSupplier discoveryClientServiceInstanceListSupplier(
            ConfigurableApplicationContext context) {
        return ServiceInstanceListSupplier.builder()
                .withDiscoveryClient()
                .withCaching()
                .withZonePreference()      // 启用区域感知
                .build(context);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12

自定义配置

public class CustomLoadBalancer implements ReactorServiceInstanceLoadBalancer {

    private final String serviceId;
    private final ServiceInstanceListSupplier serviceInstanceListSupplier;

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

    //模仿RandomLoadBalancer写的
    @Override
    public Mono<Response<ServiceInstance>> choose(Request request) {
        return serviceInstanceListSupplier.get(request)
            .next()
            .map(instances -> {
                if (instances.isEmpty()) {
                    return new EmptyResponse();
                }
                // 自定义选择逻辑
                ServiceInstance selected = customSelect(instances);
                return new DefaultResponse(selected);
            });
    }

    private ServiceInstance customSelect(List<ServiceInstance> instances) {
        // 示例:优先选择带有特定元数据的实例
        for (ServiceInstance instance : instances) {
            if ("v2".equals(instance.getMetadata().get("version"))) {
                return instance;
            }
        }
        // 回退:选择第一个
        return instances.get(0);
    }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

:注意如果负载均衡策略配置类使用spring注解@ComponentScan或者@Configuration,就要注意如果被SpringBootApplication的ComponentScan扫描到(默认扫描SpringBootApplication目录下的全部包),就会变成全局的负载均衡策略,如果需要局部负载均衡最好不用注解,或者设置不被默认的ComponentScan扫描到

# 2.3使用配置

写在启动类上

@LoadBalancerClients({@LoadBalancerClient(value = "stock-service", configuration = {CustomLoadBalancerConfiguration.class})})
1

value:使用负载均衡的服务名(nacos中注册的名字)

configuration:使用哪个配置类

@LoadBalancerClients可写多个@LoadBalancerClient

最近更新: 9/19/2026, 1:27:08 PM
编程NOTE   |