nacos提供com.alibaba.nacos.api.config.ConfigService作为客户端的API用于发布,订阅,获取配置信息;

  • ConfigService获取配置信息流程: 优先使用本地配置 --> 从nacos服务器获取配置 --> 本地快照文件获取配置

    本地文件获取路径: ${user.home}\nacos\config${serverName}_nacos\data\config-data\DEFAULT_GROUP\dataId

    服务器配置获取地址:/v1/cs/configs

    本地快照文件路径:${user.home}\nacos\config${serverName}_nacos\snapshot\DEFAULT_GROUP\dataId
public class NacosConfigService implements ConfigService {

    /**
* Get config
*
* @param dataId dataId
* @param group group
* @param timeoutMs read timeout
* @return config value
* @throws NacosException NacosException
*/
@Override
public String getConfig(String dataId, String group, long timeoutMs) throws NacosException {
return getConfigInner(namespace, dataId, group, timeoutMs);
} private String getConfigInner(String tenant, String dataId, String group, long timeoutMs) throws NacosException {
group = null2defaultGroup(group);
ParamUtils.checkKeyParam(dataId, group);
ConfigResponse cr = new ConfigResponse();
cr.setDataId(dataId);
cr.setTenant(tenant);
cr.setGroup(group); // 优先使用本地配置
String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);
if (content != null) {
LOGGER.warn("[{}] [get-config] get failover ok, dataId={}, group={}, tenant={}, config={}", agent.getName(), dataId, group, tenant, ContentUtils.truncateContent(content));
cr.setContent(content);
configFilterChainManager.doFilter(null, cr);
content = cr.getContent();
return content;
} // 从服务器端获取
try {
String[] ct = worker.getServerConfig(dataId, group, tenant, timeoutMs);
cr.setContent(ct[0]);
configFilterChainManager.doFilter(null, cr);
content = cr.getContent(); return content;
} catch (NacosException ioe) {
LOGGER.warn("[{}] [get-config] get from server error, dataId={}, group={}, tenant={}, msg={}", agent.getName(), dataId, group, tenant, ioe.toString());
} //从服务器获取失败后从快照获取
content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);
cr.setContent(content);
configFilterChainManager.doFilter(null, cr);
content = cr.getContent();
return content;
}
}

如果成功从服务器段获取到信息后更新本地快照

public class ClientWorker {
// 从服务器端获取配置信息
public String[] getServerConfig(String dataId, String group, String tenant, long readTimeout) throws NacosException {
String[] ct = new String[2];
if (StringUtils.isBlank(group)) {
group = Constants.DEFAULT_GROUP;
} HttpResult result = null;
try {
List<String> params = new ArrayList<String>(Arrays.asList("dataId", dataId, "group", group, "tenant", tenant));
result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);
} catch (IOException e) {
LOGGER.error(message, e);
throw new NacosException(NacosException.SERVER_ERROR, e);
} switch (result.code) {
case HttpURLConnection.HTTP_OK:
//更新本地快照
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content);
ct[0] = result.content;
return ct;
case HttpURLConnection.HTTP_NOT_FOUND:
//更新本地快照
LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null);
return ct;
...........................
}
}
}
  • 配置信息发布
public class NacosConfigService implements ConfigService {

    /**
* Publish config.
*
* @param dataId dataId
* @param group group
* @param content content
* @return Whether publish
* @throws NacosException NacosException
*/
private boolean publishConfigInner(String tenant, String dataId, String group, String tag, String appName, String betaIps, String content) throws NacosException {
//组织参数
............................
// POST /v1/cs/configs
String url = Constants.CONFIG_CONTROLLER_PATH;
HttpResult result = null;
try {
result = agent.httpPost(url, headers, params, encode, POST_TIMEOUT);
} catch (IOException ioe) {
return false;
} if (HttpURLConnection.HTTP_OK == result.code) {
return true;
} else if (HttpURLConnection.HTTP_FORBIDDEN == result.code) {
throw new NacosException(result.code, result.content);
} else {
return false;
}
}
}
  • 配置信息监听

    注册监听器,监听某个dataId

    客户端通过长轮询不断获取哪些(dataId)变更列表

    遍历变更的dataId列表依次调用ClientWorker.getServerConfig从服务器端获取最新信息

    回调所有注册监听此dataId的所有监听器
public class NacosConfigService implements ConfigService {
/**
* Add a listener to the configuration, after the server modified the
* configuration, the client will use the incoming listener callback.
* Recommended asynchronous processing, the application can implement the
* getExecutor method in the ManagerListener, provide a thread pool of
* execution. If provided, use the main thread callback, May block other
* configurations or be blocked by other configurations.
*
* @param dataId dataId
* @param group group
* @param listener listener
* @throws NacosException NacosException
*/
@Override
public void addListener(String dataId, String group, Listener listener) throws NacosException {
worker.addTenantListeners(dataId, group, Arrays.asList(listener));
}
}
public class ClientWorker {
/**
* groupKey -> cacheData
*/
private final AtomicReference<Map<String, CacheData>> cacheMap = new AtomicReference<Map<String, CacheData>>(new HashMap<String, CacheData>()); /**
* dataId对应的所有信息都包装成CacheData缓存到cacheMap中
* 注册监听往CacheData的 private final CopyOnWriteArrayList<ManagerListenerWrap> listeners增加一条记录
*/
public void addTenantListeners(String dataId, String group, List<? extends Listener> listeners) throws NacosException {
group = null2defaultGroup(group);
String tenant = agent.getTenant();
CacheData cache = addCacheDataIfAbsent(dataId, group, tenant);
for (Listener listener : listeners) {
cache.addListener(listener);
}
}
}

客户端长轮训获取最新配置信息:

  1. Long-Pulling-Timeout设置nacos服务器端挂起请求的时间。不低于10秒 (Math.max(10000, Long.parseLong(str) - delayTime));
  2. 如果有第一次获取数据的配置则设置 Long-Pulling-Timeout-No-Hangup=true时 nacos服务器发现没有变更的信息也不挂起请求立马返回,

    Long-Pulling-Timeout-No-Hangup != true时 nacos服务器发现没有变更信息则挂起当前请求默认最长30000毫秒或有变更后才返回。
  3. 参数Listening-Configs=probeUpdateString表示监听遍历cacheDatas拼接的订阅
 class LongPollingRunnable implements Runnable {

        @Override
public void run() {
try {
// check server config
List<String> changedGroupKeys = checkUpdateDataIds(cacheDatas, inInitializingCacheList);
//遍历变更的dataId列表
for (String groupKey : changedGroupKeys) {
try {
//从服务器端获取最新信息
String[] ct = getServerConfig(dataId, group, tenant, 3000L);
CacheData cache = cacheMap.get().get(GroupKey.getKeyTenant(dataId, group, tenant));
cache.setContent(ct[0]);
} catch (NacosException ioe) {
LOGGER.error(message, ioe);
}
}
executorService.execute(this); } catch (Throwable e) {
executorService.schedule(this, taskPenaltyTime, TimeUnit.MILLISECONDS);
}
}
}

nacos--配置中心之客户端的更多相关文章

  1. Nacos配置中心交互模型是 push 还是 pull ?你应该这么回答

    本文案例收录在 https://github.com/chengxy-nds/Springboot-Notebook 大家好,我是小富- 对于Nacos大家应该都不太陌生,出身阿里名声在外,能做动态服 ...

  2. Spring Cloud 系列之 Alibaba Nacos 配置中心

    Nacos 介绍 Nacos 是 Alibaba 公司推出的开源工具,用于实现分布式系统的服务发现与配置管理.英文全称 Dynamic Naming and Configuration Service ...

  3. Spring Cloud Config、Apollo、Nacos配置中心选型及对比

    Spring Cloud Config.Apollo.Nacos配置中心选型及对比 1.Nacos 1.1 Nacos主要提供以下四大功能 2.Spring Cloud Config 3.Apollo ...

  4. Spring Cloud Alibaba(5)---Nacos(配置中心)

    Nacos(配置中心) 有关Spring Cloud Alibaba之前写过四篇文章,这篇也是在上面项目的基础上进行开发. Spring Cloud Alibaba(1)---入门篇 Spring C ...

  5. nacos配置中心模块详解

    本文已收录 https://github.com/lkxiaolou/lkxiaolou 欢迎star. 配置中心 业务上的配置,功能开关,服务治理上对弱依赖的降级,甚至数据库的密码等,都可能用到动态 ...

  6. SpringBoot使用Nacos配置中心

    本文介绍SpringBoot如何使用阿里巴巴Nacos做配置中心. 1.Nacos简介 Nacos是阿里巴巴集团开源的一个易于使用的平台,专为动态服务发现,配置和服务管理而设计.它可以帮助您轻松构建云 ...

  7. Spring Cloud(十四)Config 配置中心与客户端的使用与详细

    前言 在上一篇 文章 中我们直接用了本应在本文中配置的Config Server,对Config也有了一个基本的认识,即 Spring Cloud Config 是一种用来动态获取Git.SVN.本地 ...

  8. Nacos配置中心

    本文介绍spring cloud 集成 nacos案例 官方文档:https://nacos.io/zh-cn/docs/what-is-nacos.html](https://nacos.io/zh ...

  9. Nacos配置中心使用

    在系统开发过程中,开发者通常会将一些需要变更的参数.变量等从代码中分离出来独立管理,以独立的配置文件的形式存在.目的是让静态的系统工件或者交付物(如 WAR,JAR 包等)更好地和实际的物理运行环境进 ...

  10. 微服务从nacos配置中心获得配置信息

    一,安装nacos, 略 二,创建父工程和微服务工程 service1, service2,以idea为例 1, new -> project -> Maven -> 填写group ...

随机推荐

  1. BZOJ1150 [CTSC2007]数据备份Backup 链表+小根堆

    BZOJ1150 [CTSC2007]数据备份Backup 题意: 给定一个长度为\(n\)的数组,要求选\(k\)个数且两两不相邻,问最小值是多少 题解: 做一个小根堆,把所有值放进去,当选择一个值 ...

  2. HDU6434 Count【欧拉函数 线性筛】

    HDU6434 I. Count T次询问,每次询问\(\sum_{i=1}^{n}\sum_{j=1}^{n-1}[gcd(i-j,i+j)=1]\) \(T\le 1e5, n \le 2e7\) ...

  3. 2019牛客多校 Round4

    Solved:3 Rank:331 B xor 题意:5e4个集合 每个集合最多32个数 5e4个询问 询问l到r个集合是不是都有一个子集的xor和等于x 题解:在牛客多校第一场学了线性基 然后这个题 ...

  4. Codeforces Round #646 (Div. 2) A. Odd Selection(数学)

    题目链接:https://codeforces.com/contest/1363/problem/A 题意 判断是否能从 $n$ 个数中选 $x$ 个数加起来和为奇数. 题解 首先 $n$ 个数中至少 ...

  5. 【poj 2407】Relatives(数论--欧拉函数 模版题)

    题意就是求10^9以内的正整数的欧拉函数(Φ(n)表示<=n的与n互质的正整数个数). 解法:用欧拉筛和欧拉函数的一些性质:    1.若p是质数,Φ(p)=p-1:    2.欧拉函数是积性函 ...

  6. uestc 1221 Ancient Go

    Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submit  Status Y ...

  7. 字典树 && 例题 Xor Sum HDU - 4825 (板子)

    一.字典树描述:Trie树,即字典树,又称单词查找树或键树,是一种树形结构,是一种哈希树的变种.典型应用是用于统计和排序大量的字符串(但不仅限于字符串),所以经常被搜索引擎系统用于文本词频统计.它的优 ...

  8. 洛谷 P4143 采集矿石 后缀数组

    题目背景 ZRQ 成功从坍塌的洞穴中逃了出来.终于,他看到了要研究的矿石.他想挑一些带回去完成任务. 题目来源:Zhang_RQ哦对了 \(ZRQ\) 就他,嗯 题目描述 ZRQ 发现这里有 \(N\ ...

  9. Leetcode(712)-账户合并

    给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该帐户的邮箱地址 ...

  10. select用法&原理详解(源码剖析)(转)

    今天遇到了在select()前后fd_set的变化问题,查了好久终于找到一个有用的帖子了,很赞,很详细!!原文链接如下: select用法&原理详解(源码剖析) 我的问题是: 如下图示:在se ...