1. 简介

随着微服务架构的普及,跨多服务器运行分布式服务已成为常态。本文将探讨如何使用 Spring Cloud Load Balancer 构建高容错应用,实现服务调用的智能负载均衡。

2. 负载均衡解析

负载均衡的本质是将流量分发到同一应用的多个实例上。为构建容错系统,我们通常会部署多个应用实例。当服务间需要通信时,必须选择特定实例处理请求。

常见的负载均衡算法包括:

  • 随机选择:随机挑选实例
  • 轮询:按固定顺序循环选择
  • 最少连接:优先选择当前连接数最少的实例
  • 加权指标:基于权重指标(如CPU/内存使用率)选择最优实例
  • IP哈希:通过客户端IP哈希映射到固定实例

每种算法各有优劣:

  • 随机和轮询实现简单但资源利用率可能不均
  • 最少连接和加权指标实现复杂但资源利用更优
  • IP哈希适合会话保持场景,但容错性较差

3. Spring Cloud Load Balancer 实战

Spring Cloud Load Balancer 库让我们能轻松实现负载均衡的服务间通信。下面通过示例演示如何创建服务端和客户端。

3.1 服务端示例

创建基础 Spring Boot 应用:

@SpringBootApplication
@RestController
public class ServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(ServerApplication.class, args);
    }

    @Value("${server.instance.id}")
    String instanceId;

    @GetMapping("/hello")
    public String hello() {
        return String.format("Hello from instance %s", instanceId);
    }
}

关键点说明:

  • 通过 instanceId 区分不同实例
  • 提供简单的 /hello 接口返回实例信息

默认实例运行在 8080 端口(ID=1)。启动第二个实例需添加参数:

--server.instance.id=2 --server.port=8081

3.2 客户端示例

添加核心依赖:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>

实现 ServiceInstanceListSupplier 接口(这是框架的核心接口):

class DemoInstanceSupplier implements ServiceInstanceListSupplier {
    private final String serviceId;

    public DemoInstanceSupplier(String serviceId) {
        this.serviceId = serviceId;
    }

    @Override
    public String getServiceId() {
        return serviceId;
    }

    @Override
    public Flux<List<ServiceInstance>> get() {
        return Flux.just(Arrays.asList(
            new DefaultServiceInstance(serviceId + "1", serviceId, "localhost", 8080, false),
            new DefaultServiceInstance(serviceId + "2", serviceId, "localhost", 8081, false)
        ));
    }
}

踩坑提醒:生产环境切勿硬编码服务地址!后续会介绍动态发现方案。

配置负载均衡客户端:

@Configuration
@LoadBalancerClient(name = "example-service", configuration = DemoServerInstanceConfiguration.class)
class WebClientConfig {
    @LoadBalanced
    @Bean
    WebClient.Builder webClientBuilder() {
        return WebClient.builder();
    }
}

关键点说明:

  • 使用伪服务名 example-service 作为占位符
  • 框架运行时会自动替换为真实实例地址

创建服务实例配置:

@Configuration
class DemoServerInstanceConfiguration {
    @Bean
    ServiceInstanceListSupplier serviceInstanceListSupplier() {
        return new DemoInstanceSupplier("example-service");
    }
}

实现客户端请求逻辑:

@SpringBootApplication
public class ClientApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext ctx = new SpringApplicationBuilder(ClientApplication.class)
          .web(WebApplicationType.NONE)
          .run(args);

        WebClient loadBalancedClient = ctx.getBean(WebClient.Builder.class).build();

        for(int i = 1; i <= 10; i++) {
            String response = loadBalancedClient.get()
              .uri("http://example-service/hello")
              .retrieve().toEntity(String.class)
              .block().getBody();
            System.out.println(response);
        }
    }
}

运行结果验证负载均衡效果:

Hello from instance 2
Hello from instance 1
Hello from instance 2
Hello from instance 1
Hello from instance 2
Hello from instance 1
Hello from instance 2
Hello from instance 1
Hello from instance 2
Hello from instance 1

4. 进阶特性

基础示例仅展示了框架的核心功能,实际开发中这些特性更值得关注:

负载均衡策略

  • 默认使用 RoundRobinLoadBalancer(轮询)
  • 提供 RandomLoadBalancer(随机)
  • 可自定义 ReactorServiceInstanceLoadBalancer 实现复杂算法

服务发现

  • 通过 DiscoveryClientServiceInstanceListSupplier 实现动态发现
  • 支持 Eureka、Zookeeper 等注册中心集成

重试机制

  • 基于 Spring Retry 库实现
  • 支持失败请求自动重试(可配置延迟策略)

监控指标

  • 内置 Micrometer 指标收集
  • 提供实例级基础监控,支持自定义指标

实例缓存

  • 通过 LoadBalancerCacheManager 缓存服务实例
  • 解决远程查询的性能瓶颈和单点故障问题

    重要提示:服务实例查询通常涉及远程调用,缓存能显著提升系统稳定性

5. 总结

负载均衡是构建现代容错系统的核心组件。Spring Cloud Load Balancer 提供了:

  • 灵活的负载均衡策略
  • 无缝的服务发现集成
  • 生产级特性(重试/监控/缓存)

通过组合这些能力,我们可以轻松实现高可用的微服务通信架构。所有示例代码可在 GitHub 获取完整实现。


原始标题:Introduction to Spring Cloud Load Balancer