Spring Boot3 客户端负载均衡全解析:从原理到实战

Spring Boot3 客户端负载均衡全解析:从原理到实战

经验文章nimo972025-07-08 19:59:215A+A-

在当今互联网软件开发领域,分布式系统架构已成为主流。其中,Spring Boot3 作为热门开发框架,其客户端负载均衡功能对于提升系统性能、保障服务稳定性起着关键作用。今天,咱们就深入探讨一下 Spring Boot3 中如何实现客户端负载均衡操作,帮各位后端技术开发的伙伴们在项目中如鱼得水。

揭开负载均衡的神秘面纱

在分布式系统里,负载均衡就像是交通枢纽的调度员,将大量的请求合理分配到多个服务器或服务实例上,目的是提高系统可用性和响应速度。而客户端负载均衡,是由客户端 (像微服务) 自行承担起这个调度任务,在微服务架构中十分常见。与之相对的是服务器端负载均衡,比如我们熟悉的 NGINX 或 HAProxy 这类部署在服务器端的负载均衡器。在 Spring Boot3 的世界里,我们可以借助 Spring Cloud LoadBalancer 或 Netflix Ribbon 来达成客户端负载均衡。

负载均衡主要承担着以下重要职责:

流量分配:就如同均匀分配糖果给小朋友,负载均衡要将流量均匀洒向多个服务实例,避免某个实例被请求淹没,出现单点过载的困境。

故障转移:当某个服务实例 “生病”(不可用) 时,负载均衡能自动将流量引导到其他健康的实例上,保证服务的持续运行,就像备用轮胎在车胎爆胎时及时顶上。

健康检查:它会定期给服务实例做 “体检”,只有健康的实例才会被纳入请求分配的范围,确保请求都能被妥善处理。

会话保持:如果业务需要,它能保证同一会话的请求始终被路由到同一个服务实例,就像老顾客每次都指定同一位服务员服务一样。

Spring Boot3 中实现客户端负载均衡的实战步骤

借助 Spring Cloud LoadBalancer 实现

引入 Spring Cloud LoadBalancer 依赖

如果选择 Spring Cloud LoadBalancer 来实现负载均衡,在 Maven 项目的 pom.xml 文件中,我们要添加关键依赖:

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

这一步就像是给房子打好地基,为后续实现负载均衡功能奠定基础。

配置 LoadBalancerClient

接下来,我们创建一个配置类来定义负载均衡策略。例如:

import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.core.RoundRobinLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@LoadBalancerClient(name = "my - service", configuration = MyLoadBalancerConfiguration.class)
public class MyLoadBalancerConfiguration {
    @Bean
    public RoundRobinLoadBalancer roundRobinLoadBalancer(LoadBalancerClientFactory clientFactory) {
        return new RoundRobinLoadBalancer(clientFactory.getLazyProvider("my - service", ServiceInstanceListSupplier.class), "my - service");
    }
}

这里我们定义了一个使用轮询策略 (Round Robin) 的负载均衡器,针对名为 “my - service” 的服务。不同的业务场景可能需要不同的负载均衡策略,比如加权响应时间策略等,我们可以根据实际情况灵活调整。

使用 LoadBalancerClient

在控制器中,我们通过 LoadBalancerClient 来挑选合适的服务实例并发送请求,代码如下:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class MyController {
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/invokeService")
    public String invokeService() {
        ServiceInstance serviceInstance = loadBalancerClient.choose("my - service");
        String url = serviceInstance.getUri().toString() + "/endpoint";
        return restTemplate.getForObject(url, String.class);
    }
}

在这段代码中,我们先通过loadBalancerClient.choose("my - service")挑选出一个可用的 “my - service” 服务实例,然后拼接出请求的 URL,最后使用 RestTemplate 发送请求并获取响应。

配置 RestTemplate

别忘了配置 RestTemplate,让它能顺利发送 HTTP 请求,代码如下:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

@Configuration
public class MyConfiguration {
    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

这样,我们就完成了使用 Spring Cloud LoadBalancer 实现客户端负载均衡的主要配置。

利用 Netflix Ribbon 实现客户端负载均衡

除了 Spring Cloud LoadBalancer,Netflix Ribbon 也是实现 Spring Boot3 客户端负载均衡的得力助手。不过需要注意的是,Netflix Ribbon 在 Spring Cloud Hoxton 版本之后已被弃用,在新项目中更推荐使用 Spring Cloud LoadBalancer ,但在维护旧项目时 Ribbon 仍然有其价值。

服务注册到 Eureka Server

首先,我们要把服务注册到 Eureka Server 中。在 Spring Boot3 项目的配置文件 (如 application.yml) 里添加 Eureka 相关配置:

spring:
  application:
    name: my-service
  eureka:
    client:
      service-url:
        defaultZone: http://localhost:8761/eureka

这一步就像是把店铺登记到商业中心,方便其他服务找到自己。

创建 RestTemplate bean 并开启负载均衡

接着,创建一个 RestTemplate bean,并通过@LoadBalanced注解开启负载均衡功能:

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;

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

这个注解就像是给 RestTemplate 贴上了 “智能调度” 的标签,让它具备负载均衡能力。

使用服务名进行服务调用

在需要调用服务的地方,直接注入 RestTemplate bean,并在请求的 URL 中用服务名替代具体的 IP 和端口,例如:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class MyController {
    @Autowired
    private RestTemplate restTemplate;

    @GetMapping("/userInfo")
    public String getUserInfo() {
        String result = restTemplate.getForObject("http://user - service/user", String.class);
        return result;
    }
}

这里我们直接用服务名 “user - service” 调用服务接口,Ribbon 会自动挑选合适的服务实例进行负载均衡,是不是很方便?

负载均衡策略大揭秘

RoundRobinRule 线性轮询策略:这是 Ribbon 的默认负载均衡策略,就像音乐播放器的列表循环播放模式,针对一系列请求,从前到后依次访问服务器列表中的实例,到了最后一个实例,再回到开头继续循环。在多个服务端的场景下,它能在一定程度上实现负载均衡,应用较为广泛。

RetryRule 线性轮询重试策略:这个策略内部还是基于线性轮询,但当访问轮询到的服务出现问题时,会在一定时间内进行重试,重试时间可通过maxRetryMillis参数配置。比如,当某个服务实例暂时出现网络波动,导致请求失败,RetryRule 会尝试再次请求,提高请求成功的概率。

WeightedResponseTimeRule 权重响应时间策略:它是对线性轮询的拓展。在普通线性轮询中,不论服务器实例性能如何,一定请求次数下都会被轮询到,这可能导致响应时间长的实例影响整体性能。而 WeightedResponseTimeRule 会记录和计算每个服务实例的响应时间,为每个实例分配一个权重值区间。如果权重值最大值小于 0.001,后续请求采用线性轮询策略;若大于 0.001,对于每个请求,会在 0 到最大权重值之间随机生成一个数,该随机数落在哪个实例的权重区间,就选择哪个实例。平均响应时间越短的服务实例,其权重区间越大,被选中的概率也就越高,从而提升系统整体效率。

在实际项目中,我们要根据业务场景、服务实例的性能状况等因素,综合考虑选择最合适的负载均衡策略,以达到最佳的系统性能。

总结

从概念理解到实战操作,再到负载均衡策略的选择,每一步都为构建更强大、稳定的微服务架构助力。希望这篇文章能帮助各位在 Spring Boot3 开发中,熟练运用客户端负载均衡,打造出更优质、高效的软件系统。

点击这里复制本文地址 以上内容由nimo97整理呈现,请务必在转载分享时注明本文地址!如对内容有疑问,请联系我们,谢谢!
qrcode

尼墨宝库 © All Rights Reserved.  蜀ICP备2024111239号-7