看源码第一步找到maven依赖展开,看看文件夹、文件名,粗略过一遍有些啥文件
如果你有直接调用源码里的方法就直接通过方法进去看怎么实现的
如果没有直接用某个方法,那就去看目录、相关文件逐步分析理解。
看到这个LocalConfig,本地配置,那进去看看
看类描述、类结构,可以看到类上写了就是为了在灾难发生时从本地恢复配置的工具,点进这个getFailoverFile方法看看
看完你就明白,nacos在你的机器用户空间目录里给你创建了nacos文件夹,下面有个config文件,把配置存储在这了,那这样的话即使你nacos挂了,他还能从内存、本地文件里去获取到配置,提高了可用性。那内存里的配置存哪里了呢,我们去看看其他文件
客户端worker,那进去看看
有个getCache方法看看
方法名getCache,获取缓存的意思,源码实现是
return cacheMap.get(GroupKey.getKeyTenant(dataId, group, tenant));
一下就懂了把,ConcurrentHashMap
这个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 result = null; try { Map params = new HashMap(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服务器的配置,读取失败的话就最后去读取快照里的