Nacos
一.市场上的注册中心
功能/服务 | Nacos | Consul | Eureka | Zookeeper | ||
---|---|---|---|---|---|---|
1.服务引入难度 | ||||||
1.1团队使用技术栈难度 | 阿里研发 | 美企HashiCorp研发 | Netflix 开发,Spring集成 | ZooKeeper诞生于Yahoo,后转入Apache孵化 | ||
1.2 服务引入项目的难易程度 | 中英文文档,上手较容易 | 英文文档,上手较为复杂 | 英文文档,上手较为简单 | |||
1.3 未来是否需要对其进行改造 | ||||||
2.实现语言 | Java | Go | java | java | ||
3.产品功能 | 服务发现和服务健康监测、动态配置服务、动态DNS服务(TODO) | 服务发现和服务健康监测、动态配置服务、Key/Value存储、多数据中心方案等 | 服务发现 | 集群管理,配置中心,命名服务等 | ||
4.控制台 | 支持 | 支持 | 支持 | 无 | ||
5.性能 | https://nacos.io/zh-cn/docs/nacos-naming-benchmark.html | 暂无 | 暂无 | 暂无 | ||
6.社区活跃度 | 较为活跃,目前国内很多中小企业都开始引用nacos | 较为活跃 | 目前相对不太活跃 | 活跃 | ||
7.生态集成 | spring,spring-boot,spring-cloud,docker,k8s,dubbo | spring,spring-boot,spring-cloud,docker,k8s,service mesh等 | spring-cloud | dubbo,kafka,hadoop等 | ||
8.劣势 | 鉴权未完善 | 使用较为复杂 | 2.0闭源,主要使用1.x; | / | ||
9.最新版本 | 2.0.3 | 1.10.0 | 1.10.16 | 3.7.0 | ||
10.其他特点 | ||||||
10.1 一致性协议 | AP/CP切换 | CP | AP | CP | ||
10.2 通信协议 | http、dns | http、dns | http | tcp | ||
10.3 健康检查 | 支持 | 支持 | 支持 | 不支持 | ||
10.4 雪崩保护(注册方几乎所有掉线,例如只留下一个注册方,那么请求方会将所有请求请求到同一台机器,造成机器直接崩溃) | 支持 | 不支持 | 支持 | 不支持 | ||
10.5 自动注销实例 | 支持 | 支持 | 支持 | 支持 | ||
10.6 负载均衡 | 权重、selector等自带 | 联合DNS或者Fabio | Ribbon联合使用 | 无 | ||
10.7 监听支持 | 支持 | 支持 | 支持 | 支持 | ||
二、开发一个注册中心需要关注点
1.服务器端的信息保存(持久化)
数据库/磁盘文件
2.服务器端提供访问api
rpc、http
3.数据变化之后如何通知到客户端
push(服务端主动推送到客户端)、pull(客户端主动拉去数据) -> 长轮训( pull数据量很大会怎么办)
4.客户端如何去获得远程服务的数据
5.服务保活,服务器健康信息检测
6.安全性
....
性能瓶颈点:
- 1)支持多少服务同时发起注册、拉取(集群大小,数据一致性协议)
- 2)服务内存是否足够容纳服务信息
- 3)服务是否会被后续的心跳信息压垮
三、Nacos功能
配置中心(支持回滚)
服务治理(AP/CP)
1.领域模型
Nacos 数据模型 Key 由三元组唯一确定, Namespace默认是空串,公共命名空间(public),分组默认是 DEFAULT_GROUP。
2.服务领域模型
四、Nacos源码之注册中心解析
版本 1.3.1
1. 服务注册
2. 服务消费
3. 线程模型
3.1 客户端核心线程模型
3.2 服务端核心线程模型
- 服务管理线程模型
- 集群服务器健康检测线程模型
-
Raft选举
4. 实例同步AP/CP比较
AP | CP | 备注 | |
---|---|---|---|
注册 | 用Distro协议处理临时实例,每一个服务注册都通过类似分片请求处理的方式转发到对应的服务器处理,然后返回成功 | 请求转发给leader,过半处理成功 | |
存储 | 存储在内存中 | 磁盘存储+内存存储,服务下次启动会自动加载这个文件 | |
信息同步 | 后台线程同步信息给其他服务器 | 过半机制后返回存储成功 | |
检测实例健康 | 客户端用ClientBeatCheckTask向上报自己还存活,通过返回下一次心跳做下一次心跳 | 服务端默认用TcupSuperSenseProcessor主动探活,这里是每个服务端分片对生产者进行探活,探活方式可以动态修改 | |
控制台健康检查失败后的表现 | 临时实例会直接从列表中被删除 | 持久化实例健康检查失败后会被标记成不健康 | |
默认情况下:注册实例属于AP,部分元数据用的CP做数据存储,比如SwitchDomain对象的数据采用CP存储,支持动态修改.
5. 其他
问题发现
1.cp实例使用默认Group写入的磁盘文件被删除
RaftCore#write 写完文件磁盘 又立即删除了
// remove old format file:
if (StringUtils.isNoneBlank(namespaceId)) {
if (datum.key.contains(Constants.DEFAULT_GROUP + Constants.SERVICE_INFO_SPLITER)) {
String oldFormatKey = datum.key
.replace(Constants.DEFAULT_GROUP + Constants.SERVICE_INFO_SPLITER, StringUtils.EMPTY);
cacheFile = cacheFile(cacheFileName(namespaceId, datum));
if (cacheFile.exists() && !cacheFile.delete()) {
Loggers.RAFT.error("[RAFT-DELETE] failed to delete old format datum: {}, value: {}", datum.key,
datum.value);
throw new IllegalStateException("failed to delete old format datum: " + datum.key);
}
}
}
2.spring-cloud-alibaba 2.1.2 没有发现可以把AP切换为CP的配置信息 目前是直接用接口来测试CP setEphemeral=false