目录
参考nacos官网资料和自己学习过程中整理的资料
Nacos是什么
nacos是springcloud alibaba微服务组件中的一员,包括注册中心和配置中心;
即:
NamingService: 命名服务,注册中心核心接口;
本文主要聊聊注册中心
ConfigService:配置服务,配置中心核心接口
Nacos 的关键特性包括:
- 服务发现和注册
- 服务健康监测
- 动态配置服务
- 动态 DNS 服务 (官网标注TODO,待做)
- 服务及其元数据管理
为什么需要注册中心
多个服务之间的访问,需要把服务的元数据信息注册到一个第三方服务器,然后每一个微服务端都从第三方服务器中获取一份注册表,由此也就引入了注册中心,统一管理注册表。
而nacos需要做哪些事儿呢?考虑以下为题
微服务下线了怎么办?
微服务上线了怎么办?
怎么检测微服务是否一直存活?
nacos多个节点怎么同步数据?
这些都是nacos需要解决的事儿!
下面我们慢慢看看nacos干了什么
Nacos注册中心架构
核心功能#重要
服务注册
:Nacos Client会通过发送REST请求的方式向Nacos Server注册自己的服务,提供自身的元数据,比如ip地址、端口等信息。Nacos Server接收到注册请求后,就会把这些元数据信息存储在一个双层的内存Map中。
服务心跳
:在服务注册后,Nacos Client会维护一个定时心跳来持续通知Nacos Server,说明服务一直处于可用状态,防止被剔除。默认5s发送一次心跳。
服务同步
:Nacos Server集群之间会互相同步服务实例,用来保证服务信息的一致性。 leader raft
服务发现
:服务消费者(Nacos Client)在调用服务提供者的服务时,会发送一个REST请求给Nacos Server,获取上面注册的服务清单,并且缓存在Nacos Client本地,同时会在Nacos Client本地开启一个定时任务定时拉取服务端最新的注册表信息更新到本地缓存
服务健康检查
:Nacos Server会开启一个定时任务用来检查注册服务实例的健康情况,对于超过15s没有收到客户端心跳的实例会将它的healthy属性置为false(客户端服务发现时不会发现),如果某个实例超过30秒没有收到心跳,直接剔除该实例(被剔除的实例如果恢复发送心跳则会重新注册)
服务注册表结构 #重要
在讲注册表结构之前,我们先看看它的领域模型
概念 |
描述 |
Namespace |
代表不同的环境,如开发dev、测试test、⽣产环境prod |
Group |
代表某项⽬,⽐如交易组 |
Service |
某个项⽬中具体xxx服务 交易组下的不同服务:订单服务,购物车服务,库存服务 |
DataId |
某个项⽬中具体的xxx配置⽂件 |
在nacos服务端中存储使用双map结构,
类:com.alibaba.nacos.naming.core.ServiceManager
/**
* Map(namespace, Map(group::serviceName, Service)).
*/
private final Map<String, Map<String, Service>> serviceMap = new ConcurrentHashMap<>();
即: Map(命名空间 , Map( 组名+服务名 , 服务 ))
其中Service服务是一个实体类,com.alibaba.nacos.naming.core.Service
里面包含服务的相关信息!
灵魂一问:你觉得注册中心应该是CP还是AP?
我觉得大部分情况下,注册中心应该是AP,如果注册中心是CP的,那么表示,当我们向注册中心注册实例或移除实例时,都要等待注册中心集群中所有节点的数据达到一致后,才算注册或移除成功,而这是比较耗时的,随着业务应用规模的增大,应用频繁的上下线,那么就会导致注册中心的压力比较大,会影响到服务发现的效率以及服务调用了,而如果注册中心是AP的,那么注册中心集群不管出现了什么情况,都是可以提供服务的,就算集群节点之间数据出现了不一致,对于业务应用而言,可能拉取到了一个已经下线了的服务节点,但是现在一般的微服务框架或组件都提供了服务容错和重试功能,也可以避免这个问题,而如果是AP,对于注册中心而言就不需要消耗太多的资源来实时的保证数据一致性了,保证最终一致性就可以了,这样注册中心的压力会小一点,另外像Zookeeper来作为注册中心,因为Zookeeper保证的就是CP,但是如果集群中如果大多数节点挂掉了,就算还剩下一些Zookeeper节点,这些节点也是不能提供服务的,所以这个也不太合适,所以综合来看,注册中心应该保证AP会更好,就像Euraka、Nacos他们默认保证的就是AP。