一、概述
1.1、Ribbon目前也进入维护模式
Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。
简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算法和服务调用。Ribbon客户端组件提供一系列完善的配置项如连接超时,重试等。简单的说,就是在配置文件中列出Load Balancer(简称LB)后面所有的机器,Ribbon会自动的帮助你基于某种规则(如简单轮询,随机连接等)去连接这些机器。我们很容易使用Ribbon实现自定义的负载均衡算法。
https://github.com/Netflix/ribbon?tab=readme-ov-file#project-status-on-maintenance
https://cloud.spring.io/spring-cloud-netflix/multi/multi__modules_in_maintenance_mode.html#_modules_in_maintenance_mode
将模块置于维护模式意味着 Spring Cloud 团队将不再向该模块添加新功能。我们将修复阻止程序错误和安全问题,还将考虑和审查来自社区的小型拉取请求。我们打算从 Greenwich 发布版本正式发布开始至少一年内继续支持这些模块。以下 Spring Cloud Netflix 模块和相应的启动器将置于维护模式:
https://spring.io/blog/2019/01/23/spring-cloud-greenwich-release-is-now-available
我们建议使用以下内容来替代这些模块提供的功能。
1.2、spring-cloud-loadbalancer概述
LB负载均衡(Load Balance)是什么
简单的说就是将用户的请求平摊的分配到多个服务上,从而达到系统的HA(高可用),常见的负载均衡有软件Nginx,LVS,硬件 F5等
spring-cloud-starter-loadbalancer组件是什么
Spring Cloud LoadBalancer是由SpringCloud官方提供的一个开源的、简单易用的客户端负载均衡器,它包含在SpringCloud-commons中用它来替换了以前的Ribbon组件。相比较于Ribbon,SpringCloud LoadBalancer不仅能够支持RestTemplate,还支持WebClient(WeClient是Spring Web Flux中提供的功能,可以实现响应式异步请求)
https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html
客户端负载VS服务器端负载区别
loadbalancer本地负载均衡客户端 VS Nginx服务端负载均衡区别
Nginx是服务器负载均衡,客户端所有请求都会交给nginx,然后由nginx实现转发请求,即负载均衡是由服务端实现的。
loadbalancer本地负载均衡,在调用微服务接口时候,会在注册中心上获取注册信息服务列表之后缓存到JVM本地,从而在本地实现RPC远程服务调用技术。
二、实战
2.1、改POM
<dependencies>
<!--loadbalancer-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
2.2、写代码
package com.loadbalancer.consumer.web;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @Author: 史小创
* @Time: 2024/8/23 下午7:08
* @Description:
*/
@RestController
public class LoadbalancerConsumerController {
public static final String URL = "http://LoadbalancerProvider/provider/";
@Autowired
private RestTemplate restTemplate;
@GetMapping(value = "/consumer/{id}")
public String hello(@PathVariable("id") Integer id) {
return restTemplate.getForObject(URL + id, String.class);
}
}
package com.loadbalancer.consumer.config;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.client.RestTemplate;
/**
* @Author: 史小创
* @Time: 2024/8/26 下午7:44
* @Description:
*/
@Configuration
public class RestTemplateConfig {
/**
* 这个注解用于启用客户端负载均衡功能。
* 注解作用在 RestTemplate 上时,Spring 会为 RestTemplate 配置一个拦截器,
* 这个拦截器会在你调用服务时自动根据服务名称(例如通过 Consul 注册中心注册的服务名)进行负载均衡。
* 也就是说,当你在 RestTemplate 中使用服务名称来调用服务时,@LoadBalanced 会确保请求被分发到不同的服务实例上,以实现负载均衡。
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
2.3、测试
http://localhost:8888/consumer/66
2.4、负载均衡的算法
https://docs.spring.io/spring-cloud-commons/reference/spring-cloud-commons/loadbalancer.html#switching-between-the-load-balancing-algorithms
在负载平衡算法之间切换 默认使用的 ReactiveLoadBalancer 实现是 RoundRobinLoadBalancer。要切换到其他实现(针对选定服务或所有服务),可以使用自定义 LoadBalancer 配置机制。例如,可以通过 @LoadBalancerClient 注释传递以下配置以切换到使用 RandomLoadBalancer:
package com.loadbalancer.consumer.config;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.loadbalancer.annotation.LoadBalancerClient;
import org.springframework.cloud.loadbalancer.core.RandomLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ReactorLoadBalancer;
import org.springframework.cloud.loadbalancer.core.ServiceInstanceListSupplier;
import org.springframework.cloud.loadbalancer.support.LoadBalancerClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.web.client.RestTemplate;
/**
* @Author: 史小创
* @Time: 2024/8/26 下午7:44
* @Description:
*/
@Configuration
/**
* @LoadBalancerClient 注解是 Spring Cloud 提供的,用于自定义特定服务的负载均衡配置。
* value 属性:value = "LoadbalancerProvider" 指定了要为哪个服务自定义负载均衡配置,这里的 "LoadbalancerProvider" 是服务的名称。
* 这个名称必须与 Consul 或其他服务注册中心中注册的服务名称完全匹配(包括大小写),因为 Spring Cloud 会根据这个名称来查找和应用负载均衡策略。
*
* configuration 属性:configuration = RestTemplateConfig.class 指定了该服务的负载均衡配置使用哪个配置类,这里指向的是当前的 RestTemplateConfig 类。
* 通过这种方式,可以为特定的服务定制负载均衡策略,例如使用随机负载均衡(RandomLoadBalancer)而不是默认的轮询负载均衡(Round Robin)。
*/
@LoadBalancerClient(
// 下面的value值大小写一定要和consul里面的名字一样,必须一样
value = "LoadbalancerProvider", configuration = RestTemplateConfig.class)
public class RestTemplateConfig {
/**
* 这个注解用于启用客户端负载均衡功能。
* 注解作用在 RestTemplate 上时,Spring 会为 RestTemplate 配置一个拦截器,
* 这个拦截器会在你调用服务时自动根据服务名称(例如通过 Consul 注册中心注册的服务名)进行负载均衡。
* 也就是说,当你在 RestTemplate 中使用服务名称来调用服务时,@LoadBalanced 会确保请求被分发到不同的服务实例上,以实现负载均衡。
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
ReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,
LoadBalancerClientFactory loadBalancerClientFactory) {
String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);
return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class), name);
}
}
http://localhost:8888/consumer/66
三、环境搭建
SpringBoot+SpringCloud的版本:
<spring.boot.version>3.2.0</spring.boot.version>
<spring.cloud.version>2023.0.0</spring.cloud.version>
注册中心:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
Consul
docker pull consul:1.9.6
docker run -d -p 8500:8500 --restart=always --name=consul -v /opt/consul:/consul/data consul:1.9.6 agent -server -bootstrap -ui -node=1 -client='0.0.0.0'
http://192.168.200.129:8500/ui/dc1/services
jdk:
Maven
IDEA
代码汇总:
https://github.com/shixiaochuangjob/markdownfile/tree/main/20240826