亚洲精品中文免费|亚洲日韩中文字幕制服|久久精品亚洲免费|一本之道久久免费

      
      

            <dl id="hur0q"><div id="hur0q"></div></dl>

                Spring Cloud Nacos配置中心實現(xiàn)原理

                環(huán)境:Springboot2.3.12.RELEASE + Spring Cloud Alibaba2.2.5.RELEASE + Spring Cloud Hoxton.SR12

                應(yīng)用的核心技術(shù)是:自定義PropertySourceLocator,然后配置spring.factories

                在如下包中配置:

                spring-cloud-context-xxx.jar中

                org.springframework.cloud.bootstrap.BootstrapConfiguration=org.springframework.cloud.bootstrap.config.PropertySourceBootstrapConfiguration

                Nacos加載配置的時候默認(rèn)會通過一下三個DataId加載數(shù)據(jù)

                核心類:NacosPropertySourceLocator

              1. dataId=nacos-config, tenant(namespace)=7205e694-ac51-4ac1-bbe9-87c28689b88a, group=HisGroup
              2. loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup, fileExtension, true);
              3. dataId=nacos-config.properties, tenant=7205e694-ac51-4ac1-bbe9-87c28689b88a, group=HisGroup
              4. loadNacosDataIfPresent(compositePropertySource, dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true);
              5. 通過定義的profile
              6. private static final String NACOS_PROPERTY_SOURCE_NAME = “NACOS”;private static final String SEP1 = “-“;private static final String DOT = “.”;for (String profile : environment.getActiveProfiles()) { String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension; loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup, fileExtension, true);}
              7. 自動配置核心

                @Configuration(proxyBeanMethods = false)@ConditionalOnProperty(name = “spring.cloud.nacos.config.enabled”, matchIfMissing = true)public class NacosConfigBootstrapConfiguration { // Nacos Config相關(guān)的配置屬性 @Bean @ConditionalOnMissingBean public NacosConfigProperties nacosConfigProperties() { return new NacosConfigProperties(); } // 管理Nacos Config相關(guān)的服務(wù) @Bean @ConditionalOnMissingBean public NacosConfigManager nacosConfigManager( NacosConfigProperties nacosConfigProperties) { return new NacosConfigManager(nacosConfigProperties); } // 核心類自定義啟動加載配置文件(Bootstraps) @Bean public NacosPropertySourceLocator nacosPropertySourceLocator( NacosConfigManager nacosConfigManager) { return new NacosPropertySourceLocator(nacosConfigManager); }}org.springframework.cloud.bootstrap.BootstrapConfiguration=com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration

                自定義屬性源

                public class NacosPropertySourceLocator implements PropertySourceLocator { private NacosPropertySourceBuilder nacosPropertySourceBuilder; private NacosConfigProperties nacosConfigProperties; private NacosConfigManager nacosConfigManager; public NacosPropertySourceLocator(NacosConfigManager nacosConfigManager) { this.nacosConfigManager = nacosConfigManager; this.nacosConfigProperties = nacosConfigManager.getNacosConfigProperties(); } public PropertySource locate(Environment env) { nacosConfigProperties.setEnvironment(env); // 關(guān)鍵通過NacosConfigManager獲取ConfigService服務(wù) ConfigService configService = nacosConfigManager.getConfigService(); // … long timeout = nacosConfigProperties.getTimeout(); nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService, timeout); // 下面這些設(shè)置就是對應(yīng)從配置文件中獲取 String name = nacosConfigProperties.getName(); String dataIdPrefix = nacosConfigProperties.getPrefix(); if (StringUtils.isEmpty(dataIdPrefix)) { dataIdPrefix = name; } if (StringUtils.isEmpty(dataIdPrefix)) { dataIdPrefix = env.getProperty(“spring.application.name”); } CompositePropertySource composite = new CompositePropertySource( NACOS_PROPERTY_SOURCE_NAME);// NACOS_PROPERTY_SOURCE_NAME = NACOS // 加載共享配置 loadSharedConfiguration(composite); // 加載擴(kuò)展配置 loadExtConfiguration(composite); // 加載應(yīng)用程序配置(這里就以應(yīng)用程序配置,深入查看) loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env); return composite; }}

                獲取配置服務(wù)

                ConfigService配置服務(wù)是獲取配置信息的核心方法:

                public interface ConfigService { // 獲取配置 String getConfig(String dataId, String group, long timeoutMs) throws NacosException; // 獲取配置并設(shè)置監(jiān)聽 String getConfigAndSignListener(String dataId, String group, long timeoutMs, Listener listener) throws NacosException; // 給配置添加監(jiān)聽 void addListener(String dataId, String group, Listener listener) throws NacosException; // 發(fā)布配置 boolean publishConfig(String dataId, String group, String content) throws NacosException; // 刪除配置 boolean removeConfig(String dataId, String group) throws NacosException; // 刪除監(jiān)聽 void removeListener(String dataId, String group, Listener listener); // 獲取服務(wù)狀態(tài) String getServerStatus(); // 關(guān)閉資源服務(wù) void shutDown() throws NacosException;}

                NacosConfigManager

                public class NacosConfigManager { private static ConfigService service = null; private NacosConfigProperties nacosConfigProperties; public NacosConfigManager(NacosConfigProperties nacosConfigProperties) { this.nacosConfigProperties = nacosConfigProperties; // 創(chuàng)建配置服務(wù) createConfigService(nacosConfigProperties); } static ConfigService createConfigService( NacosConfigProperties nacosConfigProperties) { if (Objects.isNull(service)) { synchronized (NacosConfigManager.class) { try { if (Objects.isNull(service)) { // 通過工廠創(chuàng)建服務(wù) // assembleConfigServiceProperties方法 // 就是收集關(guān)于Nacos所有配置信息,如:地址,端口,用戶名,密碼等 // 詳細(xì)查看NacosConfigProperties#assembleConfigServiceProperties service = NacosFactory.createConfigService( nacosConfigProperties.assembleConfigServiceProperties()); } } // … } } return service; }}// NacosFactorypublic class NacosFactory { public static ConfigService createConfigService(Properties properties) throws NacosException { return ConfigFactory.createConfigService(properties); }}public class ConfigFactory { 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); // 通過反射構(gòu)造了NacosConfigservice,同時設(shè)置屬性信息 // 這些屬性信息就是一些Naocs服務(wù)的地址,端口,用戶名,密碼等信息 return vendorImpl; } catch (Throwable e) { throw new NacosException(NacosException.CLIENT_INVALID_PARAM, e); } }}

                到此就得到了一個ConfigService服務(wù)類NacosConfigService。

                獲取應(yīng)用程序配置

                接著95.2獲取到了ConfigService以后繼續(xù)執(zhí)行

                public class NacosPropertySourceLocator implements PropertySourceLocator { private NacosPropertySourceBuilder nacosPropertySourceBuilder; public PropertySource locate(Environment env) { nacosConfigProperties.setEnvironment(env); // 關(guān)鍵通過NacosConfigManager獲取ConfigService服務(wù) ConfigService configService = nacosConfigManager.getConfigService(); // … nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService, timeout); CompositePropertySource composite = new CompositePropertySource( NACOS_PROPERTY_SOURCE_NAME); loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env); return composite; } private void loadApplicationConfiguration( CompositePropertySource compositePropertySource, String dataIdPrefix, NacosConfigProperties properties, Environment environment) { // 獲取文件擴(kuò)展 String fileExtension = properties.getFileExtension(); // 獲取分組 String nacosGroup = properties.getGroup(); // … // load with suffix, which have a higher priority than the default // 這里就以這里為例 loadNacosDataIfPresent(compositePropertySource, dataIdPrefix + DOT + fileExtension, nacosGroup, fileExtension, true); // Loaded with profile, which have a higher priority than the suffix // 這里會根據(jù)不同配置的profiles再次加載不同環(huán)境的配置 for (String profile : environment.getActiveProfiles()) { String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension; loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup, fileExtension, true); } } private void loadNacosDataIfPresent(final CompositePropertySource composite, final String dataId, final String group, String fileExtension, boolean isRefreshable) { if (null == dataId || dataId.trim().length() < 1) { return; } if (null == group || group.trim().length() < 1) { return; } // 加載Nacos屬性源 NacosPropertySource propertySource = this.loadNacosPropertySource(dataId, group, fileExtension, isRefreshable); this.addFirstPropertySource(composite, propertySource, false); } private NacosPropertySource loadNacosPropertySource(final String dataId, final String group, String fileExtension, boolean isRefreshable) { // … return nacosPropertySourceBuilder.build(dataId, group, fileExtension, isRefreshable); } private void addFirstPropertySource(final CompositePropertySource composite, NacosPropertySource nacosPropertySource, boolean ignoreEmpty) { if (null == nacosPropertySource || null == composite) { return; } if (ignoreEmpty && nacosPropertySource.getSource().isEmpty()) { return; } composite.addFirstPropertySource(nacosPropertySource); }}// 這里面開始加載數(shù)據(jù)public class NacosPropertySourceBuilder { NacosPropertySource build(String dataId, String group, String fileExtension, boolean isRefreshable) { Map p = loadNacosData(dataId, group, fileExtension); NacosPropertySource nacosPropertySource = new NacosPropertySource(group, dataId, p, new Date(), isRefreshable); NacosPropertySourceRepository.collectNacosPropertySource(nacosPropertySource); return nacosPropertySource; } // 加載數(shù)據(jù) private Map loadNacosData(String dataId, String group, String fileExtension) { String data = null; try { // 通過ConfigService加載配置內(nèi)容(從遠(yuǎn)程服務(wù)獲?。? data = configService.getConfig(dataId, group, timeout); if (StringUtils.isEmpty(data)) { return EMPTY_MAP; } Map dataMap = NacosDataParserHandler.getInstance() .parseNacosData(data, fileExtension); return dataMap == null ? EMPTY_MAP : dataMap; } // … return EMPTY_MAP; }}public class NacosConfigService implements ConfigService { 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); // 這里會從緩存文件中獲取,如果能獲取就不會再從遠(yuǎn)程加載了 // 會從如下緩存目錄下加載配置: // System.getProperty("JM.SNAPSHOT.PATH", // System.getProperty("user.home")) + File.separator + "nacos" // + File.separator + "config" String content = LocalConfigInfoProcessor.getFailover(agent.getName(), dataId, group, tenant); if (content != null) { cr.setContent(content); configFilterChainManager.doFilter(null, cr); content = cr.getContent(); return content; } try { // 緩存總無法獲取則從遠(yuǎn)程服務(wù)上拉取數(shù)據(jù) String[] ct = worker.getServerConfig(dataId, group, tenant, timeoutMs); cr.setContent(ct[0]); configFilterChainManager.doFilter(null, cr); content = cr.getContent(); return content; } catch (NacosException ioe) { if (NacosException.NO_RIGHT == ioe.getErrCode()) { throw ioe; } } content = LocalConfigInfoProcessor.getSnapshot(agent.getName(), dataId, group, tenant); cr.setContent(content); configFilterChainManager.doFilter(null, cr); content = cr.getContent(); return content; }}public class ClientWorker implements Closeable { // 這里就是從遠(yuǎn)程服務(wù)拉取配置 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; } 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) { throw new NacosException(NacosException.SERVER_ERROR, ex); } switch (result.getCode()) { case HttpURLConnection.HTTP_OK: // 獲取成功后會將數(shù)據(jù)保存到緩存目錄下 LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, result.getData()); ct[0] = result.getData(); if (result.getHeader().getValue(CONFIG_TYPE) != null) { ct[1] = result.getHeader().getValue(CONFIG_TYPE); } else { ct[1] = ConfigType.TEXT.getType(); } return ct; case HttpURLConnection.HTTP_NOT_FOUND: LocalConfigInfoProcessor.saveSnapshot(agent.getName(), dataId, group, tenant, null); return ct; case HttpURLConnection.HTTP_CONFLICT: { throw new NacosException(NacosException.CONFLICT, "data being modified, dataId=" + dataId + ",group=" + group + ",tenant=" + tenant); } throw new NacosException(result.getCode(), result.getMessage()); } default: { throw new NacosException(result.getCode(), "http error, code=" + result.getCode() + ",dataId=" + dataId + ",group=" + group + ",tenant=" + tenant); } } }}

                到此就完成了遠(yuǎn)程配置數(shù)據(jù)的加載

                總結(jié):Nacos Config先從本地緩存中獲取數(shù)據(jù),如果不能獲取才從遠(yuǎn)程拉?。ㄈ绻h(yuǎn)程服務(wù)無法連接,那么會不斷重試,前提是本地能夠加載到數(shù)據(jù),否則服務(wù)將無法正常啟動)。

                完畢?。。?/p>

                Spring MVC 異步請求方式 Spring中的@Configuration注解你真的了解嗎? Spring Retry重試框架的應(yīng)用 Spring容器這些擴(kuò)展點你都清楚了嗎? Spring MVC 異常處理方式 SpringBoot WebFlux整合Spring Security進(jìn)行權(quán)限認(rèn)證 Spring 自定義Advisor以編程的方式實現(xiàn)AOP

                鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場,版權(quán)歸原作者所有,如有侵權(quán)請聯(lián)系管理員(admin#wlmqw.com)刪除。
                用戶投稿
                上一篇 2022年6月13日 21:14
                下一篇 2022年6月13日 21:14

                相關(guān)推薦

                • 計算機(jī)網(wǎng)絡(luò)技術(shù)論文(計算機(jī)網(wǎng)絡(luò)技術(shù)論文七千字)

                  今天小編給各位分享計算機(jī)網(wǎng)絡(luò)技術(shù)論文的知識,其中也會對計算機(jī)網(wǎng)絡(luò)技術(shù)論文七千字進(jìn)行解釋,如果能碰巧解決你現(xiàn)在面臨的問題,別忘了關(guān)注本站,現(xiàn)在開始吧! 計算機(jī)網(wǎng)絡(luò)方面的論文3000字…

                  2022年11月26日
                • 《寶可夢朱紫》獒教父屬性是什么?獒教父屬性一覽

                  寶可夢朱紫里獒教父是一只很強(qiáng)的寶可夢,很多玩家不清楚獒教父的屬性是什么樣的,下面就給大家?guī)韺毧蓧糁熳祥峤谈笇傩砸挥[,感興趣的小伙伴一起來看看吧,希望能幫助到大家。 獒教父屬性一覽…

                  2022年11月25日
                • 《寶可夢朱紫》太晶化強(qiáng)力寶可夢推薦 太晶化哪些寶可夢最強(qiáng)?

                  寶可夢朱紫游戲中寶可夢種類繁多,不過有的寶可夢比較強(qiáng),有的稍弱一些,那么太晶化化哪些寶可夢最強(qiáng)呢,為了便于大家更好的體驗游戲,這里給大家?guī)砹藢毧蓧糁熳咸Щ瘡?qiáng)力寶可夢推薦,一起來…

                  2022年11月25日
                • 寶可夢朱紫四大天王屬性怎么樣 四大天王屬性數(shù)值介紹

                  寶可夢朱紫四大天王屬性如何?四大天王的屬性數(shù)值玩家們還是挺好奇的,想要了解四大天王屬性的可以看看下面小編的介紹,小編會把四大天王的屬性數(shù)值全都分享在下面,各位趕緊來小編這里多了解一…

                  2022年11月25日
                • 寶可夢朱紫皮卡丘多少級進(jìn)化 皮卡丘進(jìn)化條件攻略

                  寶可夢朱紫皮卡丘進(jìn)化條件是什么?皮卡丘怎么進(jìn)化?作為最受歡迎的電屬性寶可夢,大家都很想知道皮卡丘進(jìn)化的方法,今天小編這就在下面的攻略中分享皮卡丘進(jìn)化條件,各位可以趕緊來小編這里了解…

                  2022年11月25日
                • 什么是推廣cpa一篇文章帶你看懂CPA推廣渠道

                  CPA渠道 CPA指的是按照指定的行為結(jié)算,可以是搜索,可以是注冊,可以是激活,可以是搜索下載激活,可以是綁卡,實名認(rèn)證,可以是付費,可以是瀏覽等等。甲乙雙方可以根據(jù)自己的情況來定…

                  2022年11月25日
                • 沈陽茂業(yè)中心

                  由深圳贏商網(wǎng)茂業(yè)集團(tuán)與上海建工集團(tuán)聯(lián)袂打造的沈陽金廊第一高樓沈陽茂業(yè)中心于2011年11月8日順利實現(xiàn)主塔樓結(jié)構(gòu)封頂至此,歷經(jīng)四年,沈陽茂業(yè)中心以31095m的高度雄踞東北超高層建…

                  2022年11月25日
                • 抖音直播帶貨有哪些方法技巧(抖音直播帶貨有哪些痛點)

                  如今抖音這個短視頻的變現(xiàn)能力越來越突顯了,尤其是在平臺上開通直播,更具有超強(qiáng)的帶貨屬性,已經(jīng)有越來越多的普通人加入到其中了。不過直播帶貨雖然很火,但是也不是每個人都能做好的,那么在…

                  2022年11月24日
                • 《原神》3.2無相交響詩第一天無相之冰怎么打?無相交響詩攻略

                  原神3.2無相交響詩第一天無相之冰怎么打?最近新版本3.2版本的無相交響詩活動又開啟了,不少玩家還不清楚具體的玩法,下面一起來看一下原神被隱去的原神3.2無相交響詩第一天無相之冰打…

                  2022年11月24日
                • 《寶可夢朱紫》四天王屬性是什么?四天王屬性陣容一覽

                  寶可夢朱紫中玩家可以挑戰(zhàn)四天王,很多玩家想知道寶可夢朱紫四天王屬性是什么,有什么陣容?下面就帶來寶可夢朱紫四天王屬性陣容一覽,感興趣的小伙伴不要錯過,希望能幫助到大家。 四天王屬性…

                  2022年11月24日

                聯(lián)系我們

                聯(lián)系郵箱:admin#wlmqw.com
                工作時間:周一至周五,10:30-18:30,節(jié)假日休息