前言
我们的生产环境相对是比较恶劣的,我们需要对服务的流量进行更加精细的控制.Nacos支持多种负载均衡策略,包括配置权重,同机房,同地域,同环境等
一、服务下线
当某一个节点上接口的性能较差时,我们可以第一时间对该节点进行下线
操作步骤: 服务详情 -> 下线
点击下线以后,我们再请求该服务接口,会发现没有服务请求出来了
此处我们的order服务远程调用了product服务,但由于下线了9091端口的实例,所以导致它接收不到请求,所以右边的日志也没有变化
再次单击上线,该节点就会继续接收请求
二、权重配置
我们也可以通过配置节点的流量权重,来解决某些节点性能较低的问题
-
操作步骤:找到对应节点-编辑->在弹出的窗口修改权重
-
光在nacos服务端上配置了还不够,由于SpringcloudLoadBalance组件自身有负载均衡配置方式,所以不支持Nacos的权重属性配置我们需要开启Nacos的负载均衡策略,让权重配置生效
spring:
cloud:
loadbalancer:
nacos:
enabled: true
配置完成后我们重新启动服务,再多次发送请求:
通过观察我们可以发现刚才配置了权重为0.1的9091节点处理的请求数明显比9092的要少
可能出现的问题:
当修改权重时,可能会出现报错,报错信息可能如下
caused: errCode: 500, errMsg: do metadata operation failed ;caused:
com.alibaba.nacos.consistency.exception.ConsistencyException: The Raft Group
[naming_instance_metadata] did not find the Leader node;caused: The Raft Group
[naming_instance_metadata] did not find the Leader node;
原因:Nacos采用raft算法来计算Leader,并且会记录前一次启动的集群地址,当服务器IP改变时会导致raft记录的集群地址失效,导致选Leader出现问题.(网络环境发生变化时,IP地址也会发生变化)
解决办法:删除Nacos根目录下data文件夹下的protocol文件夹即可
三、同一个集群优先访问
Nacos把同一个机房内的实例,划分为一个集群.所以同集群优先访问,在一定程度上也可以理解为同机房优先访问
微服务架构中,一个服务通常有多个实例共同提供服务,这些实例可以部署在不同的机器上,这些机器可以分布在不同的机房,比如product-service:
实例1:分布在上海机房
实例2:分布在北京机房
实例3:分布在北京机房
微服务访问时,应尽量访问同机房的实例.当本机房内实例不可用时,才访问其他机房的实例
比如order-service在上海机房,product-service在北京和上海机房都有实例,那我们希望可以优先访问上海机房,如果上海机房没有实例,或者实例不可用,再访问北京机房的实例通常情况下,因为同一个机房的机器属于一个局域网,局域网访问速度更快一点
给实例配置集群名称:
将前两个服务配置文件添加spring.cloud.nacos.discovery.server-addr.cluster-name项配置集群名称:
spring:
cloud:
loadbalancer:
nacos:
enabled: true
nacos:
discovery:
server-addr: http://120.26.87.94:10020/
cluster-name: SH #上海
后面两个复制出来的服务我们也来配置一下他们的集群名称:
修改完毕后启动服务器,查看Nacos管理界面
此时我们9090端口的product服务就是在SH集群上的,而9091和9092在BJ集群上
而我们的订单服务此时是配置在SH集群的
此时在频繁发起请求,就会发现只有9090端口的服务收到了请求,因为它和订单服务属于同一个集群
四、环境隔离
企业开发中,一个服务会分为开发环境,测试环境和生产环境.
- 开发环境:开发人员用于开发的服务器,是最基础的环境.一般日志级别设置较低,可能会开启一些调试信息.
- 测试环境:测试人员用来进行测试的服务器,是开发环境到生产环境的过渡环境.
- 生产环境:正式提供对外服务的环境,通常关掉调试信息.
通常情况下,这几个环境是不能互相通信的.Nacos提供了namespace(命名空间)来实现环境的隔离.
不同的namaspace的服务不可见.
默认情况下,所有服务都在同一个namespace,名为public
创建Namespace:
配置服务的“namespace”:
配置项 | Key | 默认值 | 说明 |
---|---|---|---|
命名空间 | spring.cloud.nacos.discovery.namespace | 无 | 常用场景之一是不同环境的注册的区分隔离,例如开发测试环境和生产环境的资源(如配置、服务)隔离等. |
spring:
cloud:
nacos:
discovery:
namespace: #命名空间id
我们现在将order-service的命名空间配置为dev, product-service的命名空间配置为test, 然后重启服务观察:
现在order-service已经在dev这个命名空间下了
而所有的product-service都在test里了
测试接口:
此时因为我们的order-service在它所在的命名空间里没有product-service的服务实例,导致远程调用就失败了
查看报错日志: