深入剖析Nacos服务发现与注册,及如何基于LoadBalancer实现负载均衡
一、Nacos架构总览
1. Nacos 总体概览
Nacos 核心由三个子系统构成:
┌──────────────┐│ Clients │└─────┬────────┘│┌─────▼──────────┐│ Nacos Server│├───────────────┤│1. Naming 模块 │→ 服务注册/发现│2. Config 模块 │→ 配置发布/监听│3. Console UI │→ 运维管理└─────┬──────────┘│┌────▼────┐│Storage │→ MySQL(默认)或嵌入式 Derby└─────────┘
-
客户端:Spring Cloud、Dubbo、K8S、OpenAPI 等集成。
-
Nacos Server:提供 Naming(服务注册与发现)+ Config(配置管理)功能。
-
Storage:默认使用 MySQL 持久化注册信息和配置,支持集群部署。
2. Naming 模块(服务注册与发现)
2.1 核心流程
-
服务注册
-
客户端通过 gRPC/HTTP 请求将服务信息注册到 Nacos。
-
Server 将服务实例信息缓存于内存,并写入数据库。
-
-
心跳维持
-
客户端周期性发送心跳(默认 5 秒)表示“我在线”。
-
超过心跳超时时间(默认 15 秒)未续约,将标记为不健康。
-
-
服务发现
-
客户端请求获取某服务的所有健康实例(根据权重/策略过滤)。
-
Nacos 支持基于 Push(默认 UDP 通知)+ Pull 的混合模型。
-
-
服务下线
-
客户端主动注销,或 Server 检测超时剔除。
-
2.2 核心数据结构
Service:- name- list<Instance>- metadata- selector- protectThresholdInstance:- ip- port- weight- clusterName- ephemeral(临时)- healthy(是否健康)
2.3 数据同步机制
-
单节点:数据存于内存 + 持久化。
-
集群:使用 Raft 协议 + Distro 协议 进行节点间同步。
-
Raft 用于小数据(如配置)一致性。
-
Distro 用于大数据量服务注册信息的最终一致性。
-
3. Config 模块(配置管理)
3.1 核心概念
-
Data ID:配置项唯一标识(如
application.yaml
)。 -
Group:配置分组(如
DEFAULT_GROUP
)。 -
Namespace:租户级别的隔离,用于多环境(dev/test/prod)隔离。
3.2 配置发布流程
-
客户端拉取配置(支持长轮询 + Push)。
-
客户端监听配置变化(
/listener
接口)。 -
服务端将变更推送给所有监听者。
-
配置缓存于内存,同时写入数据库。
3.3 配置持久化结构(MySQL 表)
-
config_info
:主表,存放配置内容。 -
config_info_beta
:灰度发布。 -
config_info_tag
:标签发布。 -
his_config_info
:配置历史版本(用于回滚)。
4. 集群与一致性机制
4.1 集群部署
-
使用 Spring Boot + Tomcat 内嵌容器。
-
支持水平扩展,多节点部署。
-
节点间通过 gRPC(新)或 HTTP(老) 通讯。
-
数据一致性依赖两种协议:
-
Raft:用于一致性要求高的配置数据。
-
Distro:用于服务注册信息,强调最终一致性和高可用。
-
4.2 Distro 原理(服务发现部分)
-
基于每个节点管理“部分数据”。
-
Leader 将数据切片同步给其他节点(Peer Node)。
-
每个节点拥有数据副本并周期性同步状态(基于版本号/MD5 校验)。
5. 核心模块源码简析
5.1 Naming 服务注册入口
// 入口 Controller
InstanceController#register// 调用服务层
ServiceManager#registerInstance// 数据写入内存 & 发布变更事件
ConsistencyService#put
5.2 配置监听入口
// 客户端长轮询监听
ConfigServletInner#doPollingConfig// 比较配置是否有更新,MD5 hash 机制
ConfigCacheService#checkMd5
5.3 客户端同步更新逻辑
客户端使用:
-
PollingConfigRequest
长轮询配置变更。 -
BeatReactor
定期发送心跳。 -
PushReceiver
监听服务端变更通知(UDP 通信)。
6. Nacos 与 Eureka、Consul 对比
特性 | Nacos | Eureka | Consul |
---|---|---|---|
服务注册 | ✅ 支持 | ✅ 支持 | ✅ 支持 |
配置中心 | ✅ 内建 | ❌ 无 | ✅ 支持 |
一致性协议 | Raft + Distro | 基于 AP(最终一致性) | Raft |
数据持久化 | ✅(MySQL) | ❌(内存) | ✅(文件) |
动态配置推送 | ✅(Push + Long Poll) | ❌ | ✅ |
多租户隔离 | ✅ Namespace 支持 | ❌ | ❌ |
7. 运维与高可用建议
-
部署推荐:生产建议 ≥ 3 个节点 + MySQL 高可用。
-
数据隔离:用命名空间分环境;配置加标签分组。
-
心跳调优:根据网络和实例数量调整心跳周期。
-
定期清理:清理无效实例、过期配置版本。
-
安全控制:开启权限认证,限制 OpenAPI 使用权限。
8. 小结
Nacos 架构的核心设计理念是:
-
简化服务注册与配置管理的统一入口
-
结合 CP(配置)与 AP(注册)模型的平衡实现
-
高度可扩展与云原生友好
它适合中大型微服务系统,特别是对配置和注册中心统一治理要求较高的场景。
二、要深入分析 Nacos 的权重 + 负载均衡(LoadBalance)机制
1. Nacos 负载均衡是客户端实现的!
Nacos 本身不处理请求路由,它仅负责提供服务实例列表和健康状态+权重,最终由客户端负载均衡组件(如 Ribbon、Feign、Dubbo、Spring Cloud LoadBalancer)根据权重等信息完成请求分发。
1.1 场景假设
以 Spring Cloud Alibaba + Nacos + Ribbon 为例:
-
服务提供者:
user-service
,注册 3 个实例-
实例 A:权重 1.0
-
实例 B:权重 3.0
-
实例 C:权重 6.0
-
-
服务消费者:
order-service
,通过@FeignClient("user-service")
访问
2. 流程详细剖析
1. 服务注册(携带权重)
注册请求示例:
POST /nacos/v1/ns/instance
?serviceName=user-service
&ip=192.168.1.10
&port=8080
&weight=3.0
服务端处理链路:
InstanceController#register
↓
ServiceManager#registerInstance
↓
Service.addInstance(instance) // 缓存在内存
↓
Notifier#notifySubscriber // 推送变更
2. 服务订阅 + 推送机制
消费者应用启动时,会创建 NacosNamingService
客户端对象,它做了两件事:
-
向服务端注册监听(长轮询或 UDP 推送)
-
启动本地缓存定时刷新器(HostReactor)
HostReactor:Map<ServiceKey, List<Instance>> serviceInfoMap;Timer refreshScheduledFuture;
服务端一旦某个服务权重或健康状态变更,会通过 UDP 或 gRPC 将变更推送给客户端,更新 serviceInfoMap
。
3. 发起请求:进入负载均衡组件
发起请求方式:
@FeignClient("user-service")
public interface UserClient {@GetMapping("/user/{id}")User getById(@PathVariable("id") Long id);
}
这段调用链路会转入 Ribbon 或 LoadBalancer:
如果是 Ribbon:
NacosDiscoveryClient → NacosServerList#getUpdatedListOfServers
↓
NamingService.selectInstances("user-service", true) // 获取健康实例
↓
调用 NacosWeightedRule#choose
4. NacosWeightedRule:加权随机算法
源码路径:
com.alibaba.cloud.nacos.ribbon.NacosWeightedRule
实现逻辑:
public Server choose(Object key) {List<Instance> instances = namingService.selectInstances(serviceName, true);Instance instance = ExtendBalancer.getHostByRandomWeight(instances);return new NacosServer(instance);
}
核心加权随机算法如下:
public static Instance getHostByRandomWeight(List<Instance> hosts) {double totalWeight = hosts.stream().mapToDouble(Instance::getWeight).sum();double offset = Math.random() * totalWeight;for (Instance host : hosts) {offset -= host.getWeight();if (offset < 0) {return host;}}return null;
}
举例说明,权重如下:
-
A:1.0
-
B:3.0
-
C:6.0
总权重 = 10.0
随机生成 offset ∈ [0, 10),越大的权重越容易“覆盖” offset,从而被选中。
5. 实例选中后,继续请求调用
负载均衡组件最终返回一个 Server
实例(如 Ribbon 的 NacosServer
),然后由 Feign → RestTemplate 发送 HTTP 请求,调用具体的服务实例。
3. 完整请求流程图
+------------------+
| 服务注册(带权重)|
+--------+---------+|v
+-----------------------+
| Nacos Server 保存权重 |
+-----------------------+|推送或客户端拉取|v
+------------------------------+
| 客户端缓存健康实例 + 权重 |
+------------------------------+|发起请求(Feign/Ribbon)|v
+-------------------------------+
| NacosWeightedRule 负载均衡 |
| → 加权随机算法选出一个实例 |
+-------------------------------+|v
+---------------------------+
| Feign/RestTemplate 调用实例 |
+---------------------------+
4. 支持的客户端负载均衡组件
客户端框架 | 权重负载实现方式 | 是否支持 Nacos 权重 |
---|---|---|
Spring Cloud Ribbon | NacosWeightedRule (默认替换) | ✅ 支持 |
Spring Cloud LoadBalancer | 自定义 ServiceInstanceListSupplier | ✅ 支持(需手动适配) |
Dubbo | Dubbo SPI LoadBalance 实现 | ✅ 支持(配置在 metadata) |
Sentinel | 基于权重的流控策略 + 实例权重 | ✅ 支持 |
5. 动态修改权重,实时生效
服务提供者运行时动态变更权重(如灰度发布):
curl -X PUT "http://localhost:8848/nacos/v1/ns/instance
?serviceName=user-service
&ip=10.0.0.1
&port=8080
&weight=0.5"
-
立即推送变更给客户端
-
客户端缓存刷新
-
下一次请求立即应用新权重
6. 实战建议:灰度发布 / 弹性控制
权重机制可用于:
-
灰度发布:新实例权重设为
0.1
,逐步提高 -
控制热点节点:降低热点节点权重分摊压力
-
处理降级实例:降权或权重置 0 作为“软下线”
7. 小结
模块 | 描述 |
---|---|
注册中心(Nacos) | 存储实例权重字段,实时推送变更 |
客户端缓存机制 | HostReactor 缓存服务实例,定期刷新,接收推送 |
负载均衡实现 | NacosWeightedRule → 加权随机实现 |
负载选择原理 | Math.random + 权重切片,概率越大越易被选中 |
权重动态调整 | 支持实时更新,无需重启实例或客户端 |
应用场景 | 灰度发布、流量控制、实例优先级调整 |
三、深入剖析Spring Cloud LoadBalancer负载均衡
在 Spring Cloud 2020+ 版本(Spring Cloud Alibaba 2021+)中,Spring Cloud LoadBalancer(SCLB)替代 Ribbon 成为默认的负载均衡组件。
当你使用 Nacos 作为注册中心时,Nacos 提供了对 SCLB 的权重负载均衡支持,无需使用 Ribbon,但你需要了解两者整合方式的底层原理。
1. 核心组成
组件 | 作用 |
---|---|
NacosServiceInstanceListSupplier | 获取服务实例列表(含权重) |
WeightedLoadBalancer (核心) | 实现基于权重的负载均衡算法(取代默认 RoundRobin) |
ReactorLoadBalancer<ServiceInstance> | Spring Cloud LoadBalancer 的执行入口 |
2. 实现结构概览
Client Request↓
LoadBalancerInterceptor↓
ReactorLoadBalancer<ServiceInstance>↓
→ 从 ServiceInstanceListSupplier 获取实例列表
→ 选择实例(支持权重)↓
RestTemplate / WebClient 发起真实请求
3. 整合细节拆解
1. 实例列表供应器:NacosServiceInstanceListSupplier
Spring Cloud Alibaba 提供了一个自定义的实例列表供应器类:
public class NacosServiceInstanceListSupplier implements ServiceInstanceListSupplier {private final NamingService namingService;@Overridepublic Flux<List<ServiceInstance>> get() {List<Instance> instances = namingService.selectInstances(serviceId, true);return Flux.just(instances.stream().map(NacosServiceInstance::new) // 包装为 Spring 的 ServiceInstance.collect(Collectors.toList()));}
}
-
该类从 Nacos 获取所有健康实例。
-
实例中包含权重信息(保存在
Instance
对象中)。
✅ 这一步是 LoadBalancer 获取权重信息的关键入口。
2. 加权负载均衡实现:WeightedLoadBalancer
public class WeightedLoadBalancer implements ReactorServiceInstanceLoadBalancer {private final ServiceInstanceListSupplier supplier;@Overridepublic Mono<Response<ServiceInstance>> choose(Request request) {return supplier.get().next().map(serviceInstances -> {// 加权随机算法double totalWeight = 0;for (ServiceInstance instance : serviceInstances) {double weight = getWeight(instance); // 从 metadata 中取出totalWeight += weight;}double offset = Math.random() * totalWeight;for (ServiceInstance instance : serviceInstances) {offset -= getWeight(instance);if (offset < 0) {return new DefaultResponse(instance);}}return new EmptyResponse();});}
}
🧠 注意:
-
权重通过
ServiceInstance#getMetadata().get("nacos.weight")
获取 -
所以实例的权重必须设置并同步进 metadata
3. 自动配置类注入机制
在 spring-cloud-starter-alibaba-nacos-discovery
包中,有如下自动配置:
@Configuration
public class NacosLoadBalancerConfiguration {@Beanpublic ServiceInstanceListSupplier serviceInstanceListSupplier() {return new NacosServiceInstanceListSupplier(...);}@Beanpublic ReactorServiceInstanceLoadBalancer loadBalancer(ServiceInstanceListSupplier supplier) {return new WeightedLoadBalancer(supplier);}
}
✔ 自动注入了支持权重的负载均衡策略。
4. 权重来源说明
Nacos 的 Instance
对象中原生包含 weight
字段。SCLB 不认识它,所以需要转换为 ServiceInstance
时放入 metadata:
public class NacosServiceInstance implements ServiceInstance {private final Instance instance;@Overridepublic Map<String, String> getMetadata() {Map<String, String> metadata = new HashMap<>();metadata.put("nacos.weight", String.valueOf(instance.getWeight()));return metadata;}
}
5. 如何使用
1. 引入依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
2. application.yml 中开启 LoadBalancer
spring:cloud:nacos:discovery:server-addr: 127.0.0.1:8848namespace: devgroup: DEFAULT_GROUPloadbalancer:ribbon:enabled: false # 禁用 Ribbon,启用 Spring Cloud LoadBalancer
3. 设置权重示例
curl -X POST 'http://localhost:8848/nacos/v1/ns/instance' \-d 'serviceName=demo-service' \-d 'ip=192.168.1.10' \-d 'port=8080' \-d 'weight=5.0'
6. 整体调用流程图
+---------------------+
| 客户端发起 HTTP 请求 |
+---------------------+↓
+-------------------------------+
| LoadBalancerInterceptor 拦截器 |
+-------------------------------+↓
+---------------------------------------------+
| WeightedLoadBalancer → 权重随机选中实例 |
| ↑ 从 NacosServiceInstanceListSupplier 获取实例 |
+---------------------------------------------+↓
+-----------------------------+
| WebClient / RestTemplate 调用 |
+-----------------------------+
7. 对比 Ribbon 与 SCLB 的权重支持
特性 | Ribbon + Nacos | SCLB + Nacos |
---|---|---|
权重配置来源 | Instance.weight | Instance.weight → metadata 转换 |
权重算法实现 | NacosWeightedRule | WeightedLoadBalancer |
实例列表获取 | NacosServerList | NacosServiceInstanceListSupplier |
是否默认支持权重 | ✅ 默认启用 | ✅ Spring Cloud Alibaba 自动配置 |
推送变化是否生效 | ✅ 是 | ✅ 是 |
8. 小结
模块 | 说明 |
---|---|
NacosServiceInstanceListSupplier | 负责从 Nacos 拉取权重实例列表 |
WeightedLoadBalancer | 实现权重负载均衡算法 |
metadata | 将权重注入 ServiceInstance 的元数据中 |
自动装配支持 | Spring Cloud Alibaba 自动提供 LoadBalancer + 权重的整合支持 |
应用场景 | 适用于 RestTemplate、WebClient、Feign 等所有 SCLB 场景 |
四、深入剖析客户端连接 Nacos 并获取配置的全过程
要深入剖析客户端连接 Nacos 并获取配置的全过程,必须从源码和协议角度梳理完整链路,尤其是:
客户端如何连接 → 如何鉴权 → 如何获取配置 → 如何感知变更 → 如何动态更新配置。
并分析配置的结构、类型与作用。
1. 全流程总览图
客户端启动↓
读取 bootstrap.yml(配置 Nacos 地址)↓
构建 Nacos ConfigService↓
HTTP 获取配置(含 dataId、group、namespace)↓
解析配置(YAML / Properties / JSON)↓
注册长轮询线程监听配置变化↓
变更后自动回调 → 刷新 @Value / @ConfigurationProperties
2. 客户端连接 Nacos 流程详解
1. bootstrap.yml 中配置 Nacos 地址(注意不是 application.yml)
spring:application:name: order-servicecloud:nacos:config:server-addr: 127.0.0.1:8848namespace: dev-namespace-idfile-extension: yaml
此文件由 Spring Cloud Bootstrap Context 加载,早于 application.yml。
2. 构建 ConfigService 实例(客户端核心类)
由 Spring Cloud Alibaba 自动创建:
ConfigService configService = NacosFactory.createConfigService(properties);
内部底层使用的是 com.alibaba.nacos.client.config.impl.ClientWorker
ClientWorker worker = new ClientWorker(properties);
-
启动线程池
-
启动心跳线程
-
启动长轮询监听配置变更
3. 配置获取全过程(拉取 + 长轮询)
1. 获取配置:HTTP GET 请求
请求路径:
GET /nacos/v1/cs/configs
?dataId=xxx.yaml
&group=DEFAULT_GROUP
&namespace=xxxxx
客户端类调用:
String content = configService.getConfig(dataId, group, timeoutMs);
服务端逻辑:
ConfigController#getConfig → persistService.getConfigInner
返回内容为 YAML / Properties 等配置原文。
2. 解析配置内容(交由 Spring 处理)
-
读取后会注入到 Spring Environment 中
-
可通过
@Value("${xxx}")
或@ConfigurationProperties
获取
3. 注册监听配置变更(核心)
调用:
configService.addListener(dataId, group, new Listener() {public void receiveConfigInfo(String newContent) {// 触发 SpringCloud Refresh 机制}
});
监听底层由 ClientWorker
完成:
长轮询机制(默认每 10 秒)
ConfigRpcTransportClient / ClientWorker
→ 定期调用 /nacos/v1/cs/configs/listener
→ 如果有变更,立即推送新配置
配置变更后,客户端立即接收到新配置并执行回调。
4. 动态刷新配置的方式
Spring Cloud Alibaba 会将变更推送到 Spring 容器,自动刷新:
@RefreshScope
@Component
public class MyConfig {@Value("${my.setting}")private String setting;}
只要使用 @RefreshScope
,变更立即生效,无需重启服务。
4. 配置文件信息结构说明
1. 配置维度
配置项 | 说明 |
---|---|
dataId | 类似文件名,通常为 ${spring.application.name}.yaml |
group | 配置组,默认为 DEFAULT_GROUP |
namespace | 命名空间,用于环境隔离,例如 dev/test/prod |
你最终的配置路径如下:
命名空间 → 组 → dataId
2. 配置格式类型(file-extension)
Nacos 支持以下类型:
类型 | 示例 | 说明 |
---|---|---|
yaml | order-service.yaml | 推荐格式,支持层级结构 |
properties | order-service.properties | Java 原生配置格式 |
json | order-service.json | 前端服务常用,结构化强 |
text | custom-config.txt | 普通文本格式 |
3. 配置作用内容
配置中常见内容如下:
server:port: 8080spring:datasource:url: jdbc:mysql://...username: rootpassword: passcustom:featureFlag: trueretryCount: 5
配置可用于:
-
应用端口、日志级别
-
数据源配置
-
开关控制(feature toggle)
-
调整限流/重试等策略参数
5. 客户端鉴权机制(可选)
从 Nacos 2.x 开始支持用户名密码 + token 方式登录:
spring:cloud:nacos:config:username: nacospassword: nacos
客户端会调用:
POST /nacos/v1/auth/login
→ 返回 accessToken,后续请求带 token 鉴权
token 自动续约,无需人工干预。
6. 配置推送性能与优化机制
机制 | 说明 |
---|---|
长轮询机制 | 默认每 10 秒发起一次拉取或等待推送 |
多 dataId 聚合请求优化 | 一次请求监听多个配置(性能提升) |
本地快照缓存 | .nacos/snapshot 本地目录做容灾缓存 |
异常恢复机制 | 服务端不可达时回退至本地快照 |
7. 本地缓存文件结构
Nacos 客户端会将配置缓存在本地:
~/.nacos/snapshot/${namespace}/
└── ${dataId}@@${group}
-
断网或 Nacos 宕机时,会优先使用快照配置启动
-
配置变更时也会更新本地快照
8. 小结
阶段 | 机制说明 |
---|---|
客户端启动 | 读取 bootstrap.yml 构建 ConfigService 实例 |
获取配置 | 发起 /configs 请求,根据 dataId、group、namespace 获取完整配置文本 |
动态感知 | 启动长轮询线程,每 10 秒监听配置变更,触发 @RefreshScope 自动刷新 |
鉴权 | 支持用户名密码 + token 鉴权方式 |
本地容灾 | 支持本地快照缓存,服务端不可用时自动回退 |
配置内容 | 包括数据源、服务端口、开关控制、限流配置、缓存 TTL、日志级别等关键业务配置项 |
五、如何在网络隔离的多服务环境场景下使用Nacos
1. 场景描述
-
有三个服务:
A
、B
、C
-
注册中心:Nacos,A、B、C 都已注册到 Nacos
-
网络关系:
-
A ↔️ Nacos ✅
-
B ↔️ Nacos ✅
-
A ❌ B(不能直连,网络隔离)
-
C 是一个 网关服务(Spring Cloud Gateway)
-
A ↔️ C ✅,B ↔️ C ✅(A、B 都可以访问 C)
-
2. 可行解决方案:通过 Gateway 服务 C 作为 中转代理
你可以使用 Spring Cloud Gateway(C 服务)作为统一入口/跳板服务,让所有跨服务请求都通过 Gateway 转发。
设计思路
A ——调用——> C Gateway ——转发——> B
B ——调用——> C Gateway ——转发——> A
-
所有服务间的调用都通过 Gateway C 转发,绕过 A/B 网络隔离的问题。
-
A/B 调用时访问的是 C 的地址,由 C 负责将请求代理到目标服务。
3. 具体实现方案
C 服务:Spring Cloud Gateway 配置转发规则
示例:将 /b/**
转发到 B 服务实例
spring:cloud:gateway:discovery:locator:enabled: true # 启用注册中心自动转发routes:- id: b-service-routeuri: lb://Bpredicates:- Path=/b/**filters:- RewritePath=/b/(?<segment>.*), /${segment}- id: a-service-routeuri: lb://Apredicates:- Path=/a/**filters:- RewritePath=/a/(?<segment>.*), /${segment}
✅ 解释:
-
当访问
/b/xxx
时,Gateway 会将其转发给 Nacos 中的B
服务对应实例。 -
原始路径会被重写为
/xxx
,真实服务接收时不会带/b/
前缀。
A 服务如何调用 B?
A 服务代码示例:
@RestController
public class AServiceController {@Autowiredprivate RestTemplate restTemplate;@GetMapping("/call-b")public String callBViaGateway() {// 通过 gateway 的地址访问 B 服务String url = "http://C-GATEWAY/b/hello"; // C-GATEWAY = 网关地址return restTemplate.getForObject(url, String.class);}
}
-
http://C-GATEWAY/b/hello
是 A 调用网关的地址 -
网关转发到
B
的/hello
接口上
网络要求简化
连接方向 | 要求 |
---|---|
A → C Gateway | ✅ 可访问 |
B → C Gateway | ✅ 可访问 |
Gateway → A | ✅ 可访问 |
Gateway → B | ✅ 可访问 |
A ↔️ B | ❌ 不要求 |
✔ 你只需确保 A/B 能访问 Gateway,Gateway 能访问所有服务,即可实现“间接服务互调”。
4. 服务互调场景一览
调用方 | 被调用方 | 调用路径 | 是否可实现 | 原因 |
---|---|---|---|---|
A | B | A → Gateway(C) → B | ✅ | A 不可达 B,但可达 C,C 转发即可 |
B | A | B → Gateway(C) → A | ✅ | 同理 |
A | B | A → B(直连) | ❌ | 网络隔离无法连通 |
5. 安全建议
-
✅ 使用认证组件(如:Spring Security + JWT)保护 Gateway 的转发接口
-
✅ 可以通过 metadata 添加服务身份,用于内部权限控制
-
✅ 使用负载均衡(如:lb://B)保障网关转发的可用性
6. 可选优化:Feign + Gateway 转发
你也可以使用 Feign,通过配置让它调用 Gateway:
@FeignClient(name = "gateway", url = "http://C-GATEWAY")
public interface BServiceClient {@GetMapping("/b/hello")String callB();
}
7. 总结
要点 | 说明 |
---|---|
核心中转服务 | 使用 Spring Cloud Gateway(C 服务)作为中转 |
调用方式 | A/B 发起调用 → 网关路由转发 → B/A 接收 |
避免服务直连问题 | 不依赖 A/B 网络互通,只需确保 C 能访问所有服务 |
路由控制 | 基于 Nacos 服务名自动发现,或手动配置路由规则 |
可扩展性 | 支持加认证、限流、熔断、灰度、动态配置等功能 |