一、注册中心对比
Spring Cloud Eureka:
优点:
1)Spring Cloud 官方推荐
2)AP模型,数据最终一致性
3)开箱即用,具有控制台管理
缺点:
1)客户端注册服务上报所有信息,节点多的情况下,网络,服务端压力过大,且浪费内存
2)客户端更新服务信息通过简单的轮询机制,当服务数量巨大时,服务器压力过大。
3)集群伸缩性不强,服务端集群通过广播式的复制,增加服务器压力
4)Eureka2.0 闭源(Spring Cloud最新版本还是使用的1.X版本的Eureka)
Spring Cloud Zookeeper:
优点:
1)比较成熟的协调系统,dubbo,Spring cloud均可适配
2)CP模型,ZAB算法,数据强一致性
缺点:
1)维护成本较高,客户端,session状态,网络故障等问题,会导致服务异常
2)集群伸缩性限制,内存,GC和连接
3)无控制台管理
Spring cloud Consul:
优点:
1)适用于Service Mesh架构,使用于JAVA生态
2)AP模型,Raft+Gossip算法,数据最终一致性
缺点:
1)未经大规模市场验证,无法保证可靠性
2)Go语言编写,内部异常排查困难
Spring Cloud Nacos:
优点:
1)开箱即用,适用于dubbo,spring cloud
2)AP模型,数据最终一致性
3)注册中心,配置中心二合一,提供控制台管理
4)纯国产,久经双十一考验
缺点:
1)刚刚开源不久,社区热度不够,依然存在bug
2)0.5.0 注册服务无鉴权认证机制,存在风险
二、Nacos 服务注册
通过源码跟踪的形式,解析服务注册的过程及原理。
源码准备:
Nacos:
Spring Cloud Alibab:
分析Spring Cloud服务发现其实不分注册中心是eureka还是Nacos,因为,两者都是Spring Cloud的实现,SpringCloud已经将接口定义好,唯一的区别就是实现不一样。Spring Cloud将这些内容全部抽象到了spring-cloud-common包中。如果不了解,可以参考一下https://blog.csdn.net/hbuzhuhaoju/article/details/78915339。
在spring-cloud-common包中有一个类org.springframework.client.serviceregistry.ServiceRegistry;这个类是Spring Cloud服务注册的总入口,开下它的方法
image.png
register就是注册入口,deregister就是注销入口 close的关闭 getStatus获取服务的状态
register方法调用:
org.springframework.cloud.client.serviceregistry.AbstractAutoServiceRegistration类实现了ServiceRegistryfang接口,
image.png
方法中有个事件监听 @EventListener(WebServerInitializedEvent.class) ,说明服务注册,是在项目启动产生WebServerInitializedEvent 时,向注册中心进行注册
image.png
start方法调用了注册的方法
image.png
那现在我们回到ServiceRegistry接口,查看它的实现, org.springframework.cloud.alibaba.nacos.registry.NacosServiceRegistry 就是Nacos对这个接口的实现,所以,Nacos注册逻辑也从此处开始。
NacosServiceRegistry
NacosServiceRegistry类中主要实现了register方法和deregister方法。
image.png
register
image.png
首先通过registration.getNacosNamingService()方法获取都NamingService实例
image.png
image.png
NacosDiscoveryProperties.namingServiceInstance()方法调用namingServiceInstance()方法创建NamingService类,在通过namingService.registerInstance注册到nacos的服务端
NamingFactory 创建namingService方法
image.png
以下为注册犯法方法实现
image.png
第一,创建了心跳信息,且加载到了心跳执行器BeatReactor中,BeatReactor 已经在NacosNamingService创建是就已经new 出来了,查看BeatReactor 的源码,可知,BeatReactor在创建时就启动了一个定时任务ScheduledExecutorService,这个定时任务,主要工作就是不停的通过http请求发送心跳数据到Nacos服务端:
添加心跳。心跳请求地址为:/v1/ns/api/clientBeat 请求方式PUT
image.png
注册服务最终的实现,调用noacos的服务端接口为/v1/ns/instance
image.png
deregister
image.png
调用了beatReactor.removeBeatInfo(移除心跳)和serverProxy.deregisterService(注销)
image.png
beatReactor.removeBeatInfo(移除心跳)
image.png
serverProxy.deregisterService(注销)调用noacos的服务端接口为/v1/ns/instance 请求方式delete
image.png
namingService创建的方式和register方法一样,调用namingService.deregisterInstance注销
以上为nacos客户端注册和注销的实现。
NacosDiscoveryProperties
这个是nacos客户端配置
image.png
以下为NacosDiscoveryProperties中的不符代码
ConfigurationProperties("spring.cloud.nacos.discovery")
public class NacosDiscoveryProperties {
private static final Logger LOGGER = LoggerFactory
.getLogger(NacosDiscoveryProperties.class);
//NACOS发现服务器地址
private String serverAddr;
//服务的域名,通过该域名可以动态获取服务器地址。
private String endpoint;
//名称空间,不同环境的分离注册表。
private String namespace;
//nacos命名日志文件名
private String logName;
//注册表的服务名称
@Value("${spring.cloud.nacos.discovery.service:${spring.application.name:}}")
private String service;
//例如服务权重,值越大,权重越大。
private float weight = 1;
//nacos服务器的群集名称。
private String clusterName = "DEFAULT";
//应用程序启动时从本地缓存加载命名。真是负载
private String namingLoadCacheAtStart = "false";
//如果您只想订阅,但不想注册您的服务,请将其设置为false。
private boolean registerEnabled = true;
//要为服务实例注册的IP地址,如果自动检测IP工作正常,则无需设置它。
private String ip;
//您要注册哪个网络接口的IP
private String networkInterface = "";
//要为服务实例注册的端口,如果自动检测端口工作正常,则无需设置该端口。
private int port = -1;
//您的服务是否为HTTPS服务
private boolean secure = false;
//命名空间的访问键。
private String accessKey;
//名字空间的秘密钥匙
private String secretKey;
@Autowired
private InetUtils inetUtils;
@Autowired
private Environment environment;
private NamingService namingService;
····
}
nacos服务端
Nacos服务端源码分析
在前面我知道服务端的注册的地址,我们可以知道服务端处理的类为com.alibaba.nacos.naming.controllers.InstanceController,
因为注册使用请求PUT的方式,
image.png
image.png
image.png