Spring Cloud Alibaba - Nacos理论面试总结-未完结
临时实例和永久实例
临时实例和永久实例在 Nacos 中是一个非常非常重要的概念
之所以说它重要,主要是因为我在读源码的时候发现,临时实例和永久实例在底层的许多实现机制是完全不同的
临时实例
临时实例在注册到注册中心之后仅仅只保存在服务端内部一个缓存中,不会持久化到磁盘
这个服务端内部的缓存在注册中心届一般被称为服务注册表
当服务实例出现异常或者下线之后,就会把这个服务实例从服务注册表中剔除
永久实例
永久服务实例不仅仅会存在服务注册表中,同时也会被持久化到磁盘文件中
当服务实例出现异常或者下线,Nacos 只会将服务实例的健康状态设置为不健康,并不会对将其从服务注册表中剔除
所以这个服务实例的信息你还是可以从注册中心看到,只不过处于不健康状态
为什么 Nacos 要将服务实例分为临时实例和永久实例?
临时实例就比较适合于业务服务,服务下线之后可以不需要在注册中心中查看到
永久实例就比较适合需要运维的服务,这种服务几乎是永久存在的,比如说 MySQL、Redis 等等
当然如果你想改成永久实例,可以通过下面这个配置项来完成
spring cloud:
nacos:
discovery:
#ephemeral单词是临时的意思,设置成false,就是永久实例了
ephemeral: false
在 1.x 版本中,一个服务中可以既有临时实例也有永久实例,服务实例是永久还是临时是由服务实例本身决定的
但是 2.x 版本中,一个服务中的所有实例要么都是临时的要么都是永久的,是由服务决定的,而不是具体的服务实例
所以在 2.x 可以说是临时服务和永久服务
为什么 2.x 把临时还是永久的属性由实例本身决定改成了由服务决定?
其实很简单,你想想,假设对一个 MySQL 服务来说,它的每个服务实例肯定都是永久的,不会出现一些是永久的,一些是临时的情况吧
所以临时还是永久的属性由服务本身决定其实就更加合理了
服务注册
1.x 版本的实现
在 Nacos 在 1.x 版本的时候,服务注册是通过 Http 接口实现的
2.x 版本的实现
Nacos 客户端在启动的时候,会通过 gRPC 跟服务端建立长连接
这个连接会一直存在,之后客户端与服务端所有的通信都是基于这个长连接来的
当客户端发起注册的时候,就会通过这个长连接,将服务实例的信息发送给服务端
服务端拿到服务实例,跟 1.x 一样,也会存到服务注册表
除了注册之外,当注册的是临时实例时,2.x 还会将服务实例信息存储到客户端中的一个缓存中,供 Redo 操作
所谓的 Redo 操作,其实就是一个补偿机制,本质是个定时任务,默认每 3s 执行一次
这个定时任务作用是,当客户端与服务端重新建立连接时(因为一些异常原因导致连接断开)
那么之前注册的服务实例肯定还要继续注册服务端(断开连接服务实例就会被剔除服务注册表)
所以这个 Redo 操作一个很重要的作用就是重连之后的重新注册的作用