文章目录
- 1. 概述
- 2. 负载均衡器
- 3. 配置权重
- 4. 案例演示
- 4.1 环境搭建
- 4.2 默认权重
- 4.3 权重值为零
- 4.4 权重不一样
1. 概述
Nacos
服务管理模块,提供了服务权重管理功能,用于给服务实例设置权重,权重越高,被分配的流量越大,即基于权重的负载均衡。
典型的应用场景:
- 金丝雀发布:新版本上线时,开放小部分流量入口,即设置较小的权重,然后逐步增加,直到完全上线
- 根据服务器性能合理分配:性能好的服务器分配更高的权重,性能差的服务器分配较小的权重
2. 负载均衡器
在使用服务权重管理功能之前,需要对应用框架进行梳理,否则会导致流量未按照预期权重进行分配:
- 是否支持按权重分配流量的负载均衡
- 是否存在自身的负载均衡配置方式,没有使用
Nacos
的权重属性进行负载均衡
在之前的案例中使用的是以下技术栈:
Spring Cloud Alibaba
Spring Cloud Gateway
Spring Cloud OpenFign
Spring Cloud LoadBalancer
案例相关文档:
- Nacos 2.x 系列【3】服务注册
- Nacos 2.x 系列【4】服务发现
- Nacos 2.x 系列【8】集成 Spring Cloud Gateway
单个服务的流量入口,主要有外部通过网关直接访问,以及其他服务远程调用。例如订单服务,查询订单时,直接通过网关调用订单服务。下单时,通过用户服务远程调用订单服务(不一定是)。简单示意图如下:
在 Spring Cloud Gateway
和服务发现中,都使用了 Spring Cloud LoadBalancer
作为客户端负载均衡器,它负责从注册中心按照负载均衡策略查询可用实例,默认使用的是轮询策略。
<!--客户端负载均衡器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>
Spring Cloud LoadBalancer
作为官方的应用组件, Spring Cloud Alibaba
已经集成了基于Nacos
权重的负载均衡,相关源码位置如下:
在ConditionalOnLoadBalancerNacos
注解中,有一个开关配置:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
@ConditionalOnProperty(value = {"spring.cloud.loadbalancer.nacos.enabled"},havingValue = "true"
)
public @interface ConditionalOnLoadBalancerNacos {
}
所有在Spring Cloud Gateway
和服务提供者的应用配置中,都需要添加如下配置,以开启支持基于Nacos
权重的负载均衡:
spring:cloud:loadbalancer:nacos:enabled: true
3. 配置权重
权重的取值范围,在官方文档中没有看到相关说明,一般可以自定义一个范围,例如0-100
,或者0-1
的浮点类型,值越大,权重就越大。
可以通过以下方式进行权重的配置:
- 控制台服务详情页面(最简单常用)
- 客户端
SDK
Open API
在控制台中,进入服务列表,点击服务详情,在编辑实例页面中,可以配置权重:
在集成了Spring Cloud Alibaba
时,可以在application.yml
中配置:
spring:cloud:nacos:# 服务端用户名密码username: nacospassword: nacos# 服务发现discovery:# 命名空间namespace: 0faa0970-1179-4143-8aa2-cac3ee6b42ec# 服务端地址,默认:127.0.0.1:8848server-addr: 127.0.0.1:8848# 服务权重weight: 100
在官方Open API 指南中,可以看到在创建、更新实例时,可以指定权重:
4. 案例演示
4.1 环境搭建
在order-demo
订单服务中,创建查询当前启动端口的接口,用于区分当前调用的是哪个服务实例:
@RequestMapping("/order")
@RestController
public class OrderController {@Value("${server.port}")String port;@GetMapping("/getPort")public String getPort() {return port;}
}
在user-demo
用户服务中,通过Feign
调用order-demo
:
@FeignClient("order-demo")
public interface OrderFeignClient {@GetMapping("/order/getPort")String getPort();
}@RequestMapping("/feign")
@RestController
public class FeignController {@AutowiredOrderFeignClient orderFeignClient;@GetMapping("/getPort")public String getPort() {return orderFeignClient.getPort();}
}
所有服务开启支持基于Nacos
权重的负载均衡:
spring:cloud:loadbalancer:nacos:enabled: true
4.2 默认权重
启动所有服务,其中启动了两个order-demo
服务实例,启动端口分别为8080
、8081
:
查看order-demo
服务实例详情,可以看到默认的权重为1
:
通过网关,或者通过用户服务远程调用订单服务:
// 网关访问
http://localhost/order-demo/order/getPort
// 用户服务远程调用
http://localhost:9002/feign/getPort
多次访问查看接口返回的端口值,可以看到权重值一样时,默认是随机访问。
4.3 权重值为零
设置8080
端口对应服务的权重值为0
:
多次访问查看接口返回的端口值,可以看到权重值为零,该实例将不会被访问到。
4.4 权重不一样
设置8080
端口对应服务的权重值为9
:
多次访问查看接口返回的端口值,可以看到权重值越高,该实例被访问的次数越多。