nacos服务器挂了之后springboot/springcloud服务会挂吗?不会挂(顺便深入源码分析nacos配置中心客户端核心功能实现)

本文主要是介绍nacos服务器挂了之后springboot/springcloud服务会挂吗?不会挂(顺便深入源码分析nacos配置中心客户端核心功能实现),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • nacos挂了之后服务会挂吗?不会挂(深入源码分析)
    • 展开nacos客户端源码
    • 找本地缓存配置相关文件
    • 客户端内存缓存
    • 客户端健康状态
    • 获取配置的实现

nacos挂了之后服务会挂吗?不会挂(深入源码分析)

展开nacos客户端源码

看源码第一步找到maven依赖展开,看看文件夹、文件名,粗略过一遍有些啥文件
如果你有直接调用源码里的方法就直接通过方法进去看怎么实现的
如果没有直接用某个方法,那就去看目录、相关文件逐步分析理解。

在这里插入图片描述

找本地缓存配置相关文件

看到这个LocalConfig,本地配置,那进去看看

在这里插入图片描述
看类描述、类结构,可以看到类上写了就是为了在灾难发生时从本地恢复配置的工具,点进这个getFailoverFile方法看看
在这里插入图片描述

在这里插入图片描述
看完你就明白,nacos在你的机器用户空间目录里给你创建了nacos文件夹,下面有个config文件,把配置存储在这了,那这样的话即使你nacos挂了,他还能从内存、本地文件里去获取到配置,提高了可用性。那内存里的配置存哪里了呢,我们去看看其他文件

在这里插入图片描述

客户端内存缓存

客户端worker,那进去看看

在这里插入图片描述
有个getCache方法看看

在这里插入图片描述
方法名getCache,获取缓存的意思,源码实现是
return cacheMap.get(GroupKey.getKeyTenant(dataId, group, tenant));
一下就懂了把,ConcurrentHashMap<String, CacheData> cacheMap
在这里插入图片描述
在这里插入图片描述
这个key规则怎么生成的呢?看源码,其实就是直接拼接数据ID+分组+租户名 这样搞定了
在这里插入图片描述

客户端健康状态

额外顺便还看到了setHealthServer(boolean isHealthServer),设置服务器是否健康的方法,看下哪些地方调用了
在这里插入图片描述
你可以看到,这个地方去对服务发起请求之后,如果请求成功,就把nacos服务器状态设置为健康,否则设置为不健康。

在这里插入图片描述

还有getServerConfig方法,获取服务器配置,很核心的方法,我们看看怎么实现的
创建返回值、校验参数,构建请求参数,向nacos服务器发起http请求,处理相应数据
如果结果正常就保存快照,设置并返回响应,接口404的时候也一样保存快照返回响应,409请求冲突、403无权访问和其他未知情况就打印error日志抛异常,看着是不是觉得很简单,自己也能写一个nacos

public ConfigResponse getServerConfig(String dataId, String group, String tenant, long readTimeout)throws NacosException {ConfigResponse configResponse = new ConfigResponse();if (StringUtils.isBlank(group)) {group = Constants.DEFAULT_GROUP;}HttpRestResult<String> result = null;try {Map<String, String> params = new HashMap<String, String>(3);if (StringUtils.isBlank(tenant)) {params.put("dataId", dataId);params.put("group", group);} else {params.put("dataId", dataId);params.put("group", group);params.put("tenant", tenant);}result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);} catch (Exception ex) {String message = String.format("[%s] [sub-server] get server config exception, dataId=%s, group=%s, tenant=%s",agent.getName(), dataId, group, tenant);LOGGER.error(message, ex);throw new NacosException(NacosException.SERVER_ERROR, ex);}switch (result.getCode()) {case HttpURLConnection.HTTP_OK:LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.getData());configResponse.setContent(result.getData());String configType;if (result.getHeader().getValue(CONFIG_TYPE) != null) {configType = result.getHeader().getValue(CONFIG_TYPE);} else {configType = ConfigType.TEXT.getType();}configResponse.setConfigType(configType);String encryptedDataKey = result.getHeader().getValue(ENCRYPTED_DATA_KEY);LocalEncryptedDataKeyProcessor.saveEncryptDataKeySnapshot(agent.getName(), dataId, group, tenant, encryptedDataKey);configResponse.setEncryptedDataKey(encryptedDataKey);return configResponse;case HttpURLConnection.HTTP_NOT_FOUND:LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null);LocalEncryptedDataKeyProcessor.saveEncryptDataKeySnapshot(agent.getName(), dataId, group, tenant, null);return configResponse;case HttpURLConnection.HTTP_CONFLICT: {LOGGER.error("[{}] [sub-server-error] get server config being modified concurrently, dataId={}, group={}, "+ "tenant={}", agent.getName(), dataId, group, tenant);throw new NacosException(NacosException.CONFLICT,"data being modified, dataId=" + dataId + ",group=" + group + ",tenant=" + tenant);}case HttpURLConnection.HTTP_FORBIDDEN: {LOGGER.error("[{}] [sub-server-error] no right, dataId={}, group={}, tenant={}", agent.getName(),dataId, group, tenant);throw new NacosException(result.getCode(), result.getMessage());}default: {LOGGER.error("[{}] [sub-server-error]  dataId={}, group={}, tenant={}, code={}", agent.getName(),dataId, group, tenant, result.getCode());throw new NacosException(result.getCode(),"http error, code=" + result.getCode() + ",dataId=" + dataId + ",group=" + group + ",tenant="+ tenant);}}}

获取配置的实现

getConfig
在这里插入图片描述
先去查了nacos的系统变量
在这里插入图片描述
在这里插入图片描述
然后调了getLatestConfig获取最新配置方法,有多个实现,文件配置、nacos配置、springcloud配置、zookeeper配置等等,我们看nacos配置
在这里插入图片描述

优先去获取seeta的配置了,没有再去configService获取
在这里插入图片描述
在这里插入图片描述
getConfigInner,先读取了本地的配置,没有的话去读取nacos服务器的配置,读取失败的话就最后去读取快照里的
在这里插入图片描述

这篇关于nacos服务器挂了之后springboot/springcloud服务会挂吗?不会挂(顺便深入源码分析nacos配置中心客户端核心功能实现)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/900514

相关文章

SpringBoot内嵌Tomcat临时目录问题及解决

《SpringBoot内嵌Tomcat临时目录问题及解决》:本文主要介绍SpringBoot内嵌Tomcat临时目录问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录SprinjavascriptgBoot内嵌Tomcat临时目录问题1.背景2.方案3.代码中配置t

SpringBoot使用GZIP压缩反回数据问题

《SpringBoot使用GZIP压缩反回数据问题》:本文主要介绍SpringBoot使用GZIP压缩反回数据问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot使用GZIP压缩反回数据1、初识gzip2、gzip是什么,可以干什么?3、Spr

MySQL索引的优化之LIKE模糊查询功能实现

《MySQL索引的优化之LIKE模糊查询功能实现》:本文主要介绍MySQL索引的优化之LIKE模糊查询功能实现,本文通过示例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧... 目录一、前缀匹配优化二、后缀匹配优化三、中间匹配优化四、覆盖索引优化五、减少查询范围六、避免通配符开头七、使用外部搜索引擎八、分

Python实现特殊字符判断并去掉非字母和数字的特殊字符

《Python实现特殊字符判断并去掉非字母和数字的特殊字符》在Python中,可以通过多种方法来判断字符串中是否包含非字母、数字的特殊字符,并将这些特殊字符去掉,本文为大家整理了一些常用的,希望对大家... 目录1. 使用正则表达式判断字符串中是否包含特殊字符去掉字符串中的特殊字符2. 使用 str.isa

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Spring 基于XML配置 bean管理 Bean-IOC的方法

《Spring基于XML配置bean管理Bean-IOC的方法》:本文主要介绍Spring基于XML配置bean管理Bean-IOC的方法,本文给大家介绍的非常详细,对大家的学习或工作具有一... 目录一. spring学习的核心内容二. 基于 XML 配置 bean1. 通过类型来获取 bean2. 通过

Spring Boot 集成 Quartz并使用Cron 表达式实现定时任务

《SpringBoot集成Quartz并使用Cron表达式实现定时任务》本篇文章介绍了如何在SpringBoot中集成Quartz进行定时任务调度,并通过Cron表达式控制任务... 目录前言1. 添加 Quartz 依赖2. 创建 Quartz 任务3. 配置 Quartz 任务调度4. 启动 Sprin

springboot上传zip包并解压至服务器nginx目录方式

《springboot上传zip包并解压至服务器nginx目录方式》:本文主要介绍springboot上传zip包并解压至服务器nginx目录方式,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录springboot上传zip包并解压至服务器nginx目录1.首先需要引入zip相关jar包2.然

Android实现悬浮按钮功能

《Android实现悬浮按钮功能》在很多场景中,我们希望在应用或系统任意界面上都能看到一个小的“悬浮按钮”(FloatingButton),用来快速启动工具、展示未读信息或快捷操作,所以本文给大家介绍... 目录一、项目概述二、相关技术知识三、实现思路四、整合代码4.1 Java 代码(MainActivi

Java数组初始化的五种方式

《Java数组初始化的五种方式》数组是Java中最基础且常用的数据结构之一,其初始化方式多样且各具特点,本文详细讲解Java数组初始化的五种方式,分析其适用场景、优劣势对比及注意事项,帮助避免常见陷阱... 目录1. 静态初始化:简洁但固定代码示例核心特点适用场景注意事项2. 动态初始化:灵活但需手动管理代