解决方案:「Nacos源码之配置管理 九」客户端获取配置数据的流程

优采云 发布时间: 2022-11-17 03:26

  解决方案:「Nacos源码之配置管理 九」客户端获取配置数据的流程

  作者:史珍珍,CSDN博主Top5,Kafka Contributor,nacos Contributor,华为云MVP,腾讯云TVP,滴滴Kafka技术专家,KnowStreaming。

  KnowStreaming是滴滴开源的Kafka运维管控平台。有兴趣一起参与开发,又怕自己能力不够的同学可以联系我,我会做你的导师,指导你参与开源!.

  第一部分前言

  上一篇文章讲到【Nacos源码配置管理八】客户端如何获取服务端集群列表,客户端获取集群列表缓存在内存中,获取配置时需要用到; 因为需要去服务器端发起http请求获取数据;那么今天我们就来分析一下客户端是如何获取服务器数据的,看完这篇文章,你会明白以下几个问题:

  Part2 启动服务器

  客户端的数据是从服务端获取的,所以如果我们不启动服务端,客户端就获取不到数据;所以我们需要先启动服务器;如何启动参考【Nacos源码配置管理1】先阅读源码步骤,在本地启动Nacos

  Part3 启动客户端

  我们新建一个SpringBoot项目;使用Nacos sdk获取配置数据;

  然后启动项目;打断点开始调试;

  1NacosFatory.createConfigService创建配置服务类

  这个方法会得到一个ConfigService NacosConfigService的实例;它是通过返回创建的实例

   public static ConfigService createConfigService(Properties properties) throws NacosException {

try {

Class driverImplClass = Class.forName("com.alibaba.nacos.client.config.NacosConfigService");

Constructor constructor = driverImplClass.getConstructor(Properties.class);

ConfigService vendorImpl = (ConfigService) constructor.newInstance(properties);

return vendorImpl;

} catch (Throwable e) {

throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e);

}

}

  NacosConfigService是客户端的配置服务类;所有对配置数据的操作均由本实例完成;它拥有一个 ServerHttpAgent 实例;ServerHttpAgent是一个Http代理类,用于发起Http请求;它使一些数据 采集 的功能;ServerHttpAgent还持有一个ServerListManager实例,负责所有集群列表信息;在前面的文章中有​​分析;【Nacos源码配置管理八】如何获取客户端Server集群列表

  2 获取指定的配置数据

   Properties properties = new Properties();

properties.put("serverAddr", serverAddr);

properties.put("namespace","dev");

ConfigService configService = NacosFactory.createConfigService(properties);

String content = configService.getConfig(dataId, group, 5000);

System.out.println(content);

  serverAddr 和 namespace 命名空间在配置中设置。这个命名空间可以在管理后台自行创建。

  获取配置的核心代码

  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);

<p>

content = cr.getContent();

return content;

}

try {

content = worker.getServerConfig(dataId, group, tenant, timeoutMs);

cr.setContent(content);

configFilterChainManager.doFilter(null, cr);

content = cr.getContent();

return content;

} catch (NacosException ioe) {

if (NacosException.NO_RIGHT == ioe.getErrCode()) {

throw ioe;

}

LOGGER.warn("[{}] [get-config] get from server error, dataId={}, group={}, tenant={}, msg={}",

agent.getName(), dataId, group, tenant, ioe.toString());

}

LOGGER.warn("[{}] [get-config] get snapshot ok, dataId={}, group={}, tenant={}, config={}", agent.getName(),

dataId, group, tenant, ContentUtils.truncateContent(content));

content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant);

cr.setContent(content);

configFilterChainManager.doFilter(null, cr);

content = cr.getContent();

return content;

}

</p>

  更喜欢使用本地配置

  从代码中可以看出调用了LocalConfigInfoProcessor.getFailover方法

  

String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant);

  该方法的主要功能是查询客户端本地配置;这个适合什么使用场景?比如我们在本地开发调试时,为了不影响其他开发者,需要每个开发者使用自己单独的配置;这时候我们可以在本地配置一份自己的配置数据;客户将首先阅读它;

  本地配置数据的路径是什么

  这条路真的有点恶心;它很长而且不容易配置;①. 如果配置了租户(即namespace命名空间)

  /{LOCAL_SNAPSHOT_PATH}/{serverName}_nacos/data/config-data-tenant/{tenant}/{group}/{dataId}

  ②. 没有配置租户

  /{LOCAL_SNAPSHOT_PATH}/{serverName}_nacos/data/config-data/{group}/{dataId}

  以上用括号{}括起来的参数都是输入参数;现在一一分析这些输入参数

  LOCAL_SNAPSHOT_PATH:本地快照路径;可以设置Jvm属性-DJM.SNAPSHOT.PATH=/Users/shirenchuang/nacos;指定;如果没有,则默认获取Jvm属性user.home;此属性是我们计算机的主路径;无需主动设置;比如我的mac电脑是/Users/shirenchuang;获取以上属性后,添加nacos/config;比如我什么都没设置,就是: /Users/shirenchuang/nacos/configserverName: server name ;这个名字有点取巧,是ServerListManager中的name属性;name在构造方法ServerListManager(Properties属性)中设置;如果是读取配置文件中固定簇列表的方式:①。如果配置的namespace name=fixed-{ip1_port1-ip2_port2-ip3_port3}-namespace ②。如果不配置namespace name=fixed-{ip1_port1-ip2_port2-ip3_port3},比如我配置了固定集群列表serverAddr = 127.0.0.1:8848,,127.0.0.1:8849; 命名空间设置为dev;然后最终名称= fixed-127.-127.0.0.1_8849-dev;注意 https:// 会被删除 如果通过端点访问获取集群列表: ①. 如果命名空间配置name={endpoint}-{namespace} ②。如果不配置namespace name={endpoint},本地配置示例为配置tenant(即namespace)=dev,方法一配置集群;集群列表配置 127.0.0.1:8848,,127.0。0.1:8849 ;; 然后想获取dataId=com.Shirc.test.dataId ;group=DEFAULT_GROUP配置文件 命名空间设置为dev;然后最终名称= fixed-127.-127.0.0.1_8849-dev;注意 https:// 会被删除 如果通过端点访问获取集群列表: ①. 如果命名空间配置name={endpoint}-{namespace} ②。如果不配置namespace name={endpoint},本地配置示例为配置tenant(即namespace)=dev,方法一配置集群;集群列表配置 127.0.0.1:8848,,127.0。0.1:8849 ;; 然后想获取dataId=com.Shirc.test.dataId ;group=DEFAULT_GROUP配置文件 命名空间设置为dev;然后最终名称= fixed-127.-127.0.0.1_8849-dev;注意 https:// 会被删除 如果通过端点访问获取集群列表: ①. 如果命名空间配置name={endpoint}-{namespace} ②。如果不配置namespace name={endpoint},本地配置示例为配置tenant(即namespace)=dev,方法一配置集群;集群列表配置 127.0.0.1:8848,,127.0。0.1:8849 ;; 然后想获取dataId=com.Shirc.test.dataId ;group=DEFAULT_GROUP配置文件 本地配置示例是配置tenant(即namespace)=dev,方法一配置集群;集群列表配置 127.0.0.1:8848,,127.0。0.1:8849 ;; 然后想获取dataId=com.Shirc.test.dataId ;group=DEFAULT_GROUP配置文件 本地配置示例是配置tenant(即namespace)=dev,方法一配置集群;集群列表配置 127.0.0.1:8848,,127.0。0.1:8849 ;; 然后想获取dataId=com.Shirc.test.dataId ;group=DEFAULT_GROUP配置文件

  name=/Users/shirenchuang/fixed-127.-127.0.0.1_8849-dev_nacos/data/config-data/DEFAULT_GROUP/com.shirc.test.dataId

  2.使用方法2;配置命名空间=dev;端点=

  name=/Users/shirechuang/-dev/data/config-data/DEFAULT_GROUP/com.shirc.test.dataId

  那么,如果你使用第一种方法,你觉得配置本地数据真的是坑爹吗?

  所以我觉得一个一个拼接地址容易出错,那么可以在开机的时候在LocalConfigInfoProcessor.getFailoverFile中下个断点,直接取它要读取的地址,如下

  

  那么最终的文件地址为/Users/shirenchuang/nacos/config/fixed-172.16.10.61_8848_nacos/data/config-data/DEFAULT_GROUP/dataId文件名;

  路径找到了,然后在这个路径下创建你的dataId文件,因为nacos启动的时候会自动把数据dump到本地存储一个快照文件,我们可以直接把快照dataId文件复制到刚才的路径下,然后修改一些本地配置;

  二、使用服务器端配置数据

  如果本地没有配置文件,客户端会希望服务端发起Http请求获取配置数据;

  public String getServerConfig(String dataId, String group, String tenant, long readTimeout)

throws NacosException {

/**以下省略了部分代码**/

HttpResult result = null;

try {

List params = null;

if (StringUtils.isBlank(tenant)) {

params = Arrays.asList("dataId", dataId, "group", group);

} else {

params = Arrays.asList("dataId", dataId, "group", group, "tenant", tenant);

}

result = agent.httpGet(Constants.CONFIG_CONTROLLER_PATH, null, params, agent.getEncode(), readTimeout);

} catch (IOException e) {

}

switch (result.code) {

case HttpURLConnection.HTTP_OK:

LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.content);

return result.content;

case HttpURLConnection.HTTP_NOT_FOUND:

LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null);

return null;

case HttpURLConnection.HTTP_CONFLICT: {

}

case HttpURLConnection.HTTP_FORBIDDEN: {

}

default: {

}

}

}

  上面获取服务器端数据的过程如下:

  服务器地址/v1/cs/configs的Get请求;如果数据获取成功,Code code = 200;然后在本地保存一个数据快照Snapshot;与上述本地配置不同;如果返回404,则删除本地Snapshot Snapshot last uses snapshot Snapshot data

  上面从服务器获取数据后,会在本地保存一个快照数据;保存这个本地快照Snapshot有什么用?这是为了防止服务器完全无法访问,宕机后可以从本地快照中获取上次获取的数据;

  获取配置数据流程图

  在此处插入图像描述

  Part4总结

  当客户端发起获取配置数据的请求时,并不会立即请求服务器中的数据

  相反,首先检查您是否有本地配置文件;如果有则直接返回本地配置,如果没有则查看服务器中的配置数据;查询到后,会在本地创建一个快照文件Snapshot;这个快照文件是为了防止服务器宕机时,机器无法获取数据时,可以获取本地快照Snapshot并返回;

  解决方案:做好网站电脑端搜索引擎流量自然会影响移动端SEO优化的效果

  现在,越来越多的移动流量来了。可以说手机流量可以达到75%,这是你不能放弃的流量。那么如何针对移动设备优化 网站 呢?这也是很多人的共同看法。下面我们就来看看如何通过PC优化移动端。

  早在几年前,移动互联网的爆发式增长让包括百度在内的众多互联网巨头感到惊讶。好在百度对移动互​​联网的占领是及时的,无法拉倒。随后,百度站长平台发起了一场*敏*感*词*的移动网站适配活动,旨在让众多网站尽快建立移动网站。

  当时,移动客户端 网站 上的域前缀并不多。随着时间的推移, 、 、 的退出,稳定了移动互联网生态,形成了“移动网站”。主要是对应的域名前缀,就百度而言,我们的手机站是怎么获得排名和流量的呢?

  

  首先是手机 网站 的改编。所谓适配就是把你的电脑网站和手机网站一一链接起来,让搜索引擎知道你电脑上的某个页面有对应的手机页面。所以,如果用户通过手机访问你的电脑端网页,你可以利用你的技术能力,自动将电脑端网页重定向到手机端网页。当然,移动适配是一个比较大的工作量。具体内容可参考文章:百度手机适配案例分析及操作详解。

  第二,TDK字数与计算机数不一致。手机屏幕太小了。当然,它不能像计算机那样显示那么多的单词。一般网页的标题,即标题,控制在20个字符以内。描述还是80个字符,是否可以填写关键词,需要的话3-5个字符即可。

  

  除了这两件事,友情链接也要正常交换。你可以用你的手机网站交换别人的电脑网站。寻找优质的网站,当然是移动端的网站。虽然这个已有多年历史的搜索引擎的效率不是什么大问题,但如果真正的用户改变了他们与基于计算机的 网站 的友谊,然后从其他人的基于计算机的 网站 移动 网站 非常不友好。

  后一点是访问速度。在手机 网站 上,搜索引擎也强调页面打开的速度。百度认为,如果网站打开时间超过三秒,无论您的网站质量如何,都会被视为垃圾邮件。所以后来百度撤掉了mip技术,你也可以用mip来加速你的网站激活。

  除了地图有些问题,我想告诉大家,其实百度的重心几乎都在移动端。可以这样描述:如果你认识百度的人,和他们谈论网站或SEO,他们的大脑肯定会和你谈论移动网站。

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线