nacos(附加)
对,这里很多人第一次学 Nacos 都容易混淆。"客户端"并不是浏览器,也不是调用方,而是微服务实例本身。
整个过程如下:
+----------------+
| Nacos Server |
+----------------+
▲ ▲
│ │
注册(register) 心跳(beat)
│ │
│ │
+--------------------+
| User-Service |
| (Nacos Client) |
+--------------------+
+--------------------+
| Order-Service |
| (Nacos Client) |
+--------------------+
谁发送心跳?
例如你的 User-Service 启动了:
spring:
application:
name: user-service
server:
port: 8081
引入了:
spring-cloud-starter-alibaba-nacos-discovery
启动以后,会发生下面几件事:
第一步:向 Nacos 注册
User-Service 会发送 HTTP 请求:
POST /nacos/v1/ns/instance
请求内容:
serviceName=user-service
ip=192.168.1.5
port=8081
healthy=true
weight=1
发送给:
Nacos Server(注册中心)
第二步:启动心跳线程
注册成功以后,Nacos Client 会启动一个心跳任务。
源码里面有一个专门负责发送心跳的类,大致逻辑如下:
ScheduledExecutorService.scheduleAtFixedRate(
() -> sendBeat(),
5s,
5s
);
每隔大约 5 秒执行一次。
第三步:发送心跳
发送:
POST /nacos/v1/ns/instance/beat
内容类似:
{
"serviceName":"user-service",
"ip":"192.168.1.5",
"port":8081
}
发送给谁?
发送给:
Nacos Server
也就是你的注册中心。
所以流程就是:
User-Service
│
│ POST /instance/beat
▼
+----------------+
| Nacos Server |
+----------------+
为什么要发心跳?
假设:
User-Service
突然断电了。
它来不及执行:
register.deregister();
Nacos 怎么知道它已经挂了?
答案就是:
收不到心跳。
例如:
10:00:00 收到心跳
10:00:05 收到心跳
10:00:10 收到心跳
服务器宕机
之后:
10:00:15 ❌ 没收到
10:00:20 ❌ 没收到
10:00:25 ❌ 没收到
Nacos 就会认为:
192.168.1.5:8081
已经不健康
继续收不到:
删除实例
然后通知所有消费者:
user-service 少了一台机器。
Order-Service 会不会发心跳?
会!
很多人误以为只有提供者发,其实不是。
例如:
Order-Service
User-Service
Gateway
Inventory-Service
只要:
注册到了 Nacos
它都会发送自己的心跳。
因为对于 Nacos 来说,它们都是服务实例。
例如:
Order-Service
│
├── register
├── beat
▼
Nacos
User-Service
│
├── register
├── beat
▼
Nacos
所以每一个微服务都会维护自己的存活状态。
面试时可以这样回答
Nacos 的心跳是由 Nacos Client(即每个微服务实例) 主动发送给 Nacos Server(注册中心) 的。服务启动后,会先调用注册接口将自己的服务名、IP、端口等信息注册到 Nacos,然后客户端会启动一个定时任务,默认每隔约 5 秒向 Nacos Server 发送一次心跳(Beat),告诉注册中心自己仍然存活。如果 Nacos 在一定时间内收不到某个实例的心跳,就会先将其标记为不健康,持续超时后再将其从注册表中剔除,并通知订阅该服务的消费者更新本地服务列表。这样就实现了服务实例的健康检查和自动摘除。
浙公网安备 33010602011771号