SpringCloud中NacosNamingService的作用详解
NacosNamingService初始化
NacosNamingService类完成服务实例注册,撤销与获取服务实例操作。
生成方式:NacosNamingService初始化采用单例模式,使用反射生成。
NacosServiceRegistry bean初始化时,在构造中,根据nacos的属性配置文件,通过反射,初始化了NacosNamingService。
NacosServiceRegistry
public NacosServiceRegistry(NacosDiscoveryProperties nacosDiscoveryProperties) {
this.nacosDiscoveryProperties = nacosDiscoveryProperties;
this.namingService = nacosDiscoveryProperties.namingServiceInstance();
}NacosDiscoveryProperties
public NamingService namingServiceInstance() {
if (null != namingService) {
return namingService;
}
try {
namingService = NacosFactory.createNamingService(getNacosProperties());
}
catch (Exception e) {
log.error("create naming service error!properties={},e=,", this, e);
return null;
}
return namingService;
}NamingFactory
public static NamingService createNamingService(Properties properties) throws NacosException {
try {
Class<?> driverImplClass = Class.forName("com.alibaba.nacos.client.naming.NacosNamingService");
Constructor constructor = driverImplClass.getConstructor(Properties.class);
NamingService vendorImpl = (NamingService)constructor.newInstance(properties);
return vendorImpl;
} catch (Throwable e) {
throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e);
}
}NacosNamingService初始化过程
NacosNamingService初始化时,主要是进行了以下操作:
- 初始化命名空间,默认为public
- 初始化服务端地址.xxx:8848
- 初始化naocs 服务端两个webcontext,"/nacos//v1/ns"和"/nacos//v1/ns//instance"
- 初始化服务实例信息缓存目录,默认为用户目录下"/nacos/naming/public"
- 初始化日志
- 初始化事件分发器
- 初始化NamingProxy,像服务端发起请求的代理
- 初始化心跳信息,使用ScheduledThreadPoolExecutor初始化守护线程池,nacos默认5秒像服务端发起一次心跳,
- 初始化主机信息,默认不使用本地缓存。
public NacosNamingService(Properties properties) {
init(properties);
}
private void init(Properties properties) {
namespace = InitUtils.initNamespaceForNaming(properties);
initServerAddr(properties);
InitUtils.initWebRootContext();
initCacheDir();
initLogName(properties);
eventDispatcher = new EventDispatcher();
serverProxy = new NamingProxy(namespace, endpoint, serverList);
serverProxy.setProperties(properties);
beatReactor = new BeatReactor(serverProxy, initClientBeatThreadCount(properties));
hostReactor = new HostReactor(eventDispatcher, serverProxy, cacheDir, isLoadCacheAtStart(properties), initPollingThreadCount(properties));
}NacosNamingService心跳启动
客户端向服务端发起请求时,会先通过定时任务启动心跳,默认心跳为5秒一次
public void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException {
if (instance.isEphemeral()) {
BeatInfo beatInfo = new BeatInfo();
beatInfo.setServiceName(NamingUtils.getGroupedName(serviceName, groupName));
beatInfo.setIp(instance.getIp());
beatInfo.setPort(instance.getPort());
beatInfo.setCluster(instance.getClusterName());
beatInfo.setWeight(instance.getWeight());
beatInfo.setMetadata(instance.getMetadata());
beatInfo.setScheduled(false);
long instanceInterval = instance.getInstanceHeartBeatInterval();
beatInfo.setPeriod(instanceInterval == 0 ? DEFAULT_HEART_BEAT_INTERVAL : instanceInterval);
//启动心跳任务
beatReactor.addBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), beatInfo);
}
serverProxy.registerService(NamingUtils.getGroupedName(serviceName, groupName), groupName, instance);
}public void addBeatInfo(String serviceName, BeatInfo beatInfo) {
NAMING_LOGGER.info("[BEAT] adding beat: {} to beat map.", beatInfo);
String key = buildKey(serviceName, beatInfo.getIp(), beatInfo.getPort());
BeatInfo existBeat = null;
//fix #1733
if ((existBeat = dom2Beat.remove(key)) != null) {
existBeat.setStopped(true);
}
dom2Beat.put(key, beatInfo);//开启定时心跳任务
executorService.schedule(new BeatTask(beatInfo), beatInfo.getPeriod(), TimeUnit.MILLISECONDS);
MetricsMonitor.getDom2BeatSizeMonitor().set(dom2Beat.size());
}获取服务实例
@Override
public List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException {
ServiceInfo serviceInfo;
if (subscribe) {
serviceInfo = hostReactor.getServiceInfo(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));//本地map获取
} else {
serviceInfo = hostReactor.getServiceInfoDirectlyFromServer(NamingUtils.getGroupedName(serviceName, groupName), StringUtils.join(clusters, ","));//远程服务获取
}
List<Instance> list;
if (serviceInfo == null || CollectionUtils.isEmpty(list = serviceInfo.getHosts())) {
return new ArrayList<Instance>();
}
return list;
}服务实例注销
@Override
public void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException {
if (instance.isEphemeral()) {
beatReactor.removeBeatInfo(NamingUtils.getGroupedName(serviceName, groupName), instance.getIp(), instance.getPort());
}
serverProxy.deregisterService(NamingUtils.getGroupedName(serviceName, groupName), instance);
}到此这篇关于SpringCloud中NacosNamingService的作用详解的文章就介绍到这了,更多相关NacosNamingService的作用内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Springboot AOP对指定敏感字段数据加密存储的实现
本篇文章主要介绍了利用Springboot+AOP对指定的敏感数据进行加密存储以及对数据中加密的数据的解密的方法,代码详细,具有一定的价值,感兴趣的小伙伴可以了解一下2021-11-11
MybatisPlus3.3.0没有MybatisPlusInterceptor类问题的解决方法
项目使用的是mybatis-plus-extension3.3.0依赖,然后在我使用分页插件的时候,发现无法导入MybatisPlusInterceptor类所以本文给大家介绍了MybatisPlus3.3.0没有MybatisPlusInterceptor类问题的解决方法,需要的朋友可以参考下2023-12-12
Spring中的@ConditionalOnProperty注解详解
这篇文章主要介绍了Spring中的@ConditionalOnProperty注解详解,常见的@Conditionalxxx开头的注解我们称之为条件注解,常见的条件注解有,简单来讲,一般是在配置类上或者是@Bean修饰的方法上,添加此注解表示一个类是否要被Spring上下文加载,需要的朋友可以参考下2024-01-01


最新评论