1. 简介2. 负载均衡策略2.1. 负载均衡实现2.2. 负载均衡规则2.3. Ribbon负载均衡策略规则

3. 基本入门实现3.1. 搭建服务提供者3.2. 搭建服务消费者3.3. 简单说明测试3.4. 请求服务消费者接口

4. 自定义Ribbon配置4.1. 配置文件方式4.2. Spring JavaConfig 方式

5. Nacos自定义负载均衡策略5.1. 简介5.2. 消费者服务搭建

6. Ribbon主要组件7. 参考

1. 简介

Ribbon是Netflix开源的客户端负载均衡器,它在客户端实现服务调用的负载均衡,可以根据用户配置的策略从服务注册中心获取的服务列表中选择合适的实例进行请求。Ribbon不仅支持多种负载均衡策略,如轮询、随机、权重分配等,还提供了重试机制,增强了服务调用的稳定性和容错性。本文主要介绍nacos-discovery引入Ribbon,并结合Nacos实现服务间负载均衡。

2. 负载均衡策略

2.1. 负载均衡实现

两种主要方式实现服务的负载均衡:客户端级别负载均衡和服务端级别负载均衡。 1.客户端级别负载均衡(Client-side Load Balancing):客户端(通常是微服务架构中的服务消费者)负责负载均衡的逻辑。客户端从服务注册中心获取到所有可用的服务提供者的列表,并根据某种负载均衡策略(如轮询、随机、最少连接数等)选择其中一个服务实例进行调用。在Spring Cloud生态中,Ribbon就是一种典型的客户端负载均衡器。 2. 服务端级别负载均衡(Server-side Load Balancing): 在服务端负载均衡模型中,客户端发送请求到一个固定的接入点,如负载均衡器(硬件或软件形式,如Nginx等),这个接入点负责根据预定义的策略将请求分发到后端的多个服务实例上。服务端负载均衡器通常位于网络架构的边缘,它们可以根据请求的特性(如HTTP头部、URL、客户端IP等)以及服务器的性能指标(如CPU使用率、连接数、响应时间等)来进行负载均衡。 在微服务内部,客户端负载均衡更常见;而在面向公众服务或大规模分布式系统中,服务端负载均衡更为普遍。二者常结合使用,共同构建起高效、稳定且具有弹性的分布式系统。

2.2. 负载均衡规则

负载均衡规则是指导负载均衡器如何将流量或请求分配给后端服务器的一系列策略。以下是几种常见的负载均衡规则: 1.轮询(Round Robin): 这是最简单的负载均衡策略,请求会按照循环顺序分配给每一个后端服务器,每个服务器获得下一个请求的机会是均等的。 2.权重轮询(Weighted Round Robin,WRR): 类似轮询,但每个服务器可以被赋予不同的权重,权重高的服务器接受到的请求比例更大。 3. 最少连接(Least Connections): 请求总是被分配给当前连接数最少的服务器,这样可以避免某些服务器因处理过多请求而过载。 4. 加权最少连接(Weighted Least Connections,WLC): 结合了最少连接原则和权重,优先分配给连接数最少并且权重较高的服务器。 5. 源IP哈希(Source IP Hash): 根据客户端IP地址的哈希值来确定请求应该转发到哪一个服务器,以实现会话粘滞(session stickiness)。 6. 响应时间(Response Time): 根据服务器的响应时间来分配请求,将请求分配给最近响应速度快的服务器。 7. 随机(Random): 随机选择一个服务器处理请求,这种方法在服务器性能相近的情况下可以有效分散负载。

2.3. Ribbon负载均衡策略规则

策略名说明RandomRule(随机策略)随机选择服务实例进行负载均衡RoundRobinRule(轮询策略)按照服务实例列表的顺序依次分配请求。WeightedResponseTimeRule(响应时间加权策略)根据服务实例的响应时间动态调整权重,响应时间越短的服务实例权重越大,被选中的概率也就越大。BestAvailableRule(最小并发数策略)遍历服务提供者列表,选取连接数最小的⼀个服务实例。如果有相同的最小连接数,那么会调用轮询策略进行选取RetryRule(重试策略)并非标准的负载均衡策略,但在Ribbon中可以结合其他策略使用,如果某个服务实例在轮询或其他策略选定后无法正常响应,Ribbon可以尝试重试其他服务实例。ZoneAvoidanceRule(区域亲和性策略试图在多个区域间平衡负载,避免过度集中在某一个区域,综合考虑了服务实例的连接数和区域因素。AvailabilityFilteringRule(可用性过滤策略)会对服务实例进行过滤,例如,可以排除故障实例、只选择活动实例,或者根据特定规则(如服务实例的状态码)进行筛选。

3. 基本入门实现

准备工作 ●搭建一个服务提供者provider-demo,启动两个实例,注册上nacos注册中心。 ●搭建一个服务消费者consumer-demo,启动一个实例,注册上nacos注册中心。

nacos部署相关具体过程可以参考文章Spring Cloud Alibaba Nacos注册中心入门

3.1. 搭建服务提供者

创建项目作为服务提供者provider-demo。

创建maven项目引入依赖

2.3.12.RELEASE

Hoxton.SR12

2.2.8.RELEASE

org.springframework.boot

spring-boot-starter-parent

${spring.boot.version}

pom

import

org.springframework.cloud

spring-cloud-dependencies

${spring.cloud.version}

pom

import

com.alibaba.cloud

spring-cloud-alibaba-dependencies

${spring.cloud.alibaba.version}

pom

import

org.springframework.boot

spring-boot-starter-web

com.alibaba.cloud

spring-cloud-starter-alibaba-nacos-discovery

配置文件

spring:

application:

name: provider-demo # Spring 应用名

cloud:

# Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类

nacos:

discovery:

server-addr: 127.0.0.1:8848 # Nacos 服务器地址

service: ${spring.application.name}

# username: nacos # 如果开启Nacos权限认证nacos.core.auth.enabled=true, 需要配置上账号密码

# password: nacos

server:

port: ${random.int(18080,19090)} # 项目启动随机端口范围

创建接口层

@RestController

public class EchoController {

@Value("${server.port}")

private String serverPort;

/**

* 获取日志记录器

*/

private Logger logger = LoggerFactory.getLogger(EchoController.class);

@GetMapping(value = "/echo/{name}")

public String echo(@PathVariable String name) throws InterruptedException {

// 模拟请求时长

Thread.sleep(200);

// 日志打印

logger.info("echo print port:{}, name:{},",serverPort, name);

return "provider-" + serverPort + "::" + name;

}

}

启动项目

@SpringBootApplication

@EnableDiscoveryClient // 注解开启服务注册与发现功能

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

3.2. 搭建服务消费者

创建项目作为服务消费者consumer-demo,引入依赖同服服务提供者项目一致。

配置文件

spring:

application:

name: consumer-demo # Spring 应用名

cloud:

# Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类

nacos:

discovery:

server-addr: 127.0.0.1:8848 # Nacos 服务器地址

service: ${spring.application.name} # 注册到Nacos的服务名,不配置默认为应用名

# username: nacos # 如果开启Nacos权限认证nacos.core.auth.enabled=true, 需要配置上账号密码

# password: nacos

server:

port: 18081

初始化和配置RestTemplate Bean

@Configuration

public class RestTemplateConfiguration {

@Bean

@LoadBalanced

public RestTemplate restTemplate(){

return new RestTemplate();

}

}

创建接口层调用服务提供者接口

@RestController

public class TestController {

@Autowired

private RestTemplate restTemplate;

private Logger logger = LoggerFactory.getLogger(TestController.class);

/**

* 注解方式调用

* 直接通过restTemplate请求服务提供者

*/

@GetMapping("/go-test")

public String goTest(String name){

// 2. 调用接口

String requestUrl = "http://provider-demo/echo/" + name;

String response = restTemplate.getForObject (requestUrl, String.class);

logger.info("go-test, response:{}", response);

return "consumer:" + response;

}

}

启动项目

@SpringBootApplication

@EnableDiscoveryClient // 注解开启服务注册与发现功能

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

3.3. 简单说明测试

引入spring-cloud-starter-alibaba-nacos-discovery依赖默认引入 spring-cloud-netflix-ribbon依赖。因为nacos discovery组件集成了Ribbon。. nacos服务注册列表 添加@LoadBalanced注解在RestTemplate Bean上,实现客户端负载均衡。在Controller层进行断点查看。

3.4. 请求服务消费者接口

请求接口http://127.0.0.1:28080/go-test?name=leader,调用接口十次,返回结果均衡。

4. 自定义Ribbon配置

4.1. 配置文件方式

创建一个新的服务消费者,基本与3.2搭建的服务消费者一致,只需要更改application.yml配置文件中的配置。

修改application.yml配置,增加配置provider-demo.ribbon.NFLoadBalancerRuleClassName配置项

spring:

application:

name: consumer-demo # Spring 应用名

cloud:

# Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类

nacos:

discovery:

server-addr: 127.0.0.1:8848 # Nacos 服务器地址

service: ${spring.application.name}

# username: nacos # 如果开启Nacos权限认证nacos.core.auth.enabled=true, 需要配置上账号密码

# password: nacos

server:

port: 28080

provider-demo: # nacos中的服务提供者

ribbon:

NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule # 配置随机策略

测试 请求接口http://127.0.0.1:28080/go-test?name=leader,调用接口十次,返回结果随机。

4.2. Spring JavaConfig 方式

使用 Spring JavaConfig 的方式,实现 Ribbon 全局和 客户端两种级别的自定义配置。

创建一个新的服务消费者,基本与3.2搭建的服务消费者一致。 创建RibbonConfiguration,DefaultGlobalRibbonClientConfiguration,ProviderDemoRibbonClientConfiguration,代码层次结构如下。(注意DefaultGlobalRibbonClientConfiguration和ProviderDemoRibbonClientConfiguration是在单独的ribbon包下的,没有放在Application启动类扫描到的包下,因为会被容器扫描加载到,导致项目都使用相同的Ribbon配置,不能单独自定义配置客户端级别。) DefaultGlobalRibbonClientConfiguration类

@Configuration

public class DefaultGlobalRibbonClientConfiguration {

@Bean

public IRule ribbonDefaultRule() {

return new RoundRobinRule();

}

}

ProviderDemoRibbonClientConfiguration类

@Configuration

public class ProviderDemoRibbonClientConfiguration {

@Bean

@Primary // @Primary 优先选择IRule bean

public IRule ribbonCustomRule() {

return new RandomRule();

}

}

RibbonConfiguration类 负载均衡全局配置和客户端级别配置

@RibbonClients(

value = {

@RibbonClient(name = "provider-demo", configuration = ProviderDemoRibbonClientConfiguration.class) // 客户端级别的配置

},

defaultConfiguration = DefaultGlobalRibbonClientConfiguration.class // 全局配置

)

@Configuration

public class RibbonConfiguration {

}

@RibbonClients 注解,通过 defaultConfiguration 属性声明 Ribbon 全局级别的自定义配置,通过 value 属性声明多个 Ribbon 客户端级别的自定义配置。@Primary注解在Spring框架中用于标识一个bean作为首选bean,DefaultGlobalRibbonClientConfiguration 和 ProviderDemoRibbonClientConfiguration 都创建了 IRule Bean,Spring容器会优先使用带有@Primary注解的bean。

测试 请求接口http://127.0.0.1:28080/go-test?name=leader,调用接口十次,返回结果随机。

拓展说明:

对于 Ribbon 客户端级别的自定义配置,推荐使用配置文件的方式,简单方便好管理。配置文件方式的优先级高于 Spring JavaConfig 方式,客户端级别的优先级高于全局级别。

5. Nacos自定义负载均衡策略

5.1. 简介

Spring Cloud Alibaba Nacos Discovery组件集成Ribbon框架,并且自定义负载均衡策略规则 NacosRule。 a. 获得健康的方服务实例列表 b. 优先选择相同 Nacos 集群的服务实例列表,保证高性能。如果选择不到,则允许使用其它 Nacos 集群的服务实例列表,保证高可用。 c. 从服务实例列表按照权重进行随机,选择一个服务实例返回。

5.2. 消费者服务搭建

创建一个新的服务消费者,基本与3.2搭建的服务消费者一致,只需要更改application.yml配置文件中的配置。

修改application.yml配置,增加配置provider-demo.ribbon.NFLoadBalancerRuleClassName配置项。

spring:

application:

name: consumer-demo # Spring 应用名

cloud:

# Nacos 作为注册中心的配置项,对应 NacosDiscoveryProperties 配置类

nacos:

discovery:

server-addr: 127.0.0.1:8848 # Nacos 服务器地址

service: ${spring.application.name}

# username: nacos # 如果开启Nacos权限认证nacos.core.auth.enabled=true, 需要配置上账号密码

# password: nacos

server:

port: 28080

更改服务提供者其中一个实例的权重为0,点击编辑修改权重为0。服务消费者请求时,依据NacosRule策略不会选择该实例。 请求接口http://127.0.0.1:28080/go-test?name=leader,调用接口十次返回结果说明只请求到一个实例。

6. Ribbon主要组件

7. 参考

Spring Cloud Ribbon 中的7种负载均衡策略微服务负载均衡器Ribbon详解Spring Cloud Netflix

相关文章

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。