程序員你是如何使用Nacos作為配置中心的隧出?

file

假如你使用的是spring-cloud-alibaba微服務(wù)技術(shù)棧

單個服務(wù)獨(dú)有配置文件

即去除應(yīng)用程序的狀態(tài)踏志,配置統(tǒng)一外部化管理,方便進(jìn)行水平的伸縮胀瞪。

集成步驟:

假如我有一個應(yīng)用app-design;

1针余,引入依賴:

<dependency>
     <groupId>com.alibaba.cloud</groupId>
     <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
     <version>2.2.1.RELEASE</version>
 </dependency>

2, 配置文件饲鄙;

spring.cloud.nacos.config.enabled=true
spring.cloud.nacos.config.refresh-enabled=true

spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.discovery.server-addr}
spring.cloud.nacos.config.namespace=${spring.cloud.nacos.discovery.namespace}

說明如下:

屬性 說明
spring.cloud.nacos.config.server-addr=${spring.cloud.nacos.discovery.server-addr} nacos配置中心地址
spring.cloud.nacos.config.namespace=${spring.cloud.nacos.discovery.namespace} nacos的命名空間,這里跟服務(wù)發(fā)現(xiàn)的配置一致圆雁;

3忍级,使用配置的方式,同本地配置文件一樣伪朽。

@Value @PropertyConfiguration 這些注解都是支持的盈咳;

4碰凶,確認(rèn)方式质帅,比如把之前的application.properties的配置放到了配置中心炕檩;

image.png

本地啟動的時候,讀取到了8081端口和數(shù)據(jù)庫連接池的配置坚洽;

image.png

配置中心的連接原理戈稿,后面單獨(dú)整理出來,知其然并知其所以然讶舰。

服務(wù)之間共享配置文件

場景:多個后端微服務(wù)鞍盗,在同一個集群中共用中間件的配置信息。

比如 緩存redis, 消息隊(duì)列kafka, 文件服務(wù)器跳昼, 郵件服務(wù)器般甲;

那么對應(yīng)的配置文件沒有必要在所有的后端微服務(wù)中單獨(dú)存在,這些配置文件應(yīng)該放在公共配置文件中鹅颊,但是也可以被具體的后端微服務(wù)自己的獨(dú)有配置文件覆蓋敷存,使用自己的私有配置;

可結(jié)合下圖理解:

問題 回答
where are we?現(xiàn)狀 中間件配置分散在很多服務(wù)中挪略,配置繁瑣历帚,不方便統(tǒng)一管理
where are we go?目的 同一個集群的中間件只維護(hù)一份滔岳,各服務(wù)共享杠娱,也可按照需要覆蓋共享的配置;
how can we go there?實(shí)現(xiàn)路徑 基于nacos已有功能實(shí)現(xiàn)

下面是實(shí)際的coding過程和測試用例谱煤;

服務(wù)app-file;

在服務(wù)對應(yīng)的nacos的namespace中

1 引入共享配置

#共享中間件的配置
spring.cloud.nacos.config.shared-configs[0].data-id=mid.properties
spring.cloud.nacos.config.shared-configs[0].group=DEFAULT_GROUP
spring.cloud.nacos.config.shared-configs[0].refresh=true

位置: 模塊start下的src/main/resources/bootstrap.properties文件中

自描述的配置信息摊求,即引入的共享配置文件列表有哪些,可以按照需要刘离,配置各種中間件的配置信息室叉;

key 說明
data-id _the data id of extended configuration 配置文件名稱,帶上后綴硫惕;翻譯:擴(kuò)展配置文件的數(shù)據(jù)id
group _the group of extended configuration, the default value is DEFAULT_GROUP 集群名稱茧痕, 從名字來看,支持多集群的配置文件 翻譯:擴(kuò)展配置文件的集群恼除,默認(rèn)值是 DEFAULT_GROUP
refresh _whether to support dynamic refresh, the default does not support 是否刷新 翻譯:是否支持動態(tài)刷新踪旷,默認(rèn)不支持

花括號[0] ,里面的0是序號曼氛,如果有多個,按照數(shù)字自增順序進(jìn)行配置令野;

2 在nacos中新增配置文件

根據(jù)實(shí)際場景在nacos的test命名空間中新增配置文件mid.properties

image.png

3 獲取配置用例測試

測試接口代碼:

 @ApiOperation("測試獲取公共配置文件")
    @GetMapping("/config/test")
    public Response config(){
        String redisConfigServers = environment.getProperty("redis.config.servers","null");
        return SingleResponse.of(redisConfigServers);
    }

測試用例:

場景 期望結(jié)果 實(shí)際結(jié)果 是否符合預(yù)期
獲取共享配置文件中的配置 r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:6379 r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:6379
在服務(wù)獨(dú)有app-file.properties配置中重寫配置redis.config.servers=r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905 r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905 r-wz9sp7dhxjnz16bs1jzhutj.redis.rds.aliyuncs.com:637905

截圖如下:

image.png
image.png
image.png

源碼分析

掌握用法之后舀患,深入分析源碼,知其然而知其所以然气破;

starter調(diào)用封裝

使用的starter封裝聊浅;

https://github.com/alibaba/spring-cloud-alibaba/spring-cloud-alibaba-starters/spring-cloud-starter-alibaba-nacos-config

版本: 2.2.1.RELEASE

啟動的時候自動裝配的配置如下:

org.springframework.cloud.bootstrap.BootstrapConfiguration=\
com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.alibaba.cloud.nacos.NacosConfigAutoConfiguration,\
com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfiguration

org.springframework.boot.diagnostics.FailureAnalyzer=\
com.alibaba.cloud.nacos.diagnostics.analyzer.NacosConnectionFailureAnalyzer

分解一下key,看一下用途:

key 說明
org.springframework.cloud.bootstrap.BootstrapConfiguration A marker interface used as a key in <code>META-INF/spring.factories</code>. Entries in* the factories file are used to create the bootstrap application context.

翻譯:一個標(biāo)記注解用來作為key 放在META-INF/spring.factories文件中现使,文件中的條目用來創(chuàng)建啟動應(yīng)用的上下文低匙;

來源:spring-cloud-context-version.jar

value:

com.alibaba.cloud.nacos.NacosConfigBootstrapConfiguration |
| org.springframework.boot.autoconfigure.EnableAutoConfiguration | 注釋太長了,不放這里.放到附錄中碳锈。

來源:spring-boot-autoconfigure-version.jar

com.alibaba.cloud.nacos.NacosConfigAutoConfiguration,\

com.alibaba.cloud.nacos.endpoint.NacosConfigEndpointAutoConfiguration |
| org.springframework.boot.diagnostics.FailureAnalyzer | A {@code FailureAnalyzer} is used to analyze a failure and provide diagnostic* information that can be displayed to the user.

_

翻譯: FailureAnalyzer用來分析錯誤并提供診斷信息展示給到用戶

來源: spring-boot-version.jar

com.alibaba.cloud.nacos.diagnostics.analyzer.NacosConnectionFailureAnalyzer |

然后看看都自動裝配了什么努咐?以及自動裝配的過程。

springboot的方式調(diào)用殴胧;

1 NacosConfigBootstrapConfiguration

源碼:

package com.alibaba.cloud.nacos;

import com.alibaba.cloud.nacos.client.NacosPropertySourceLocator;

import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author xiaojing
 */
@Configuration(proxyBeanMethods = false)
@ConditionalOnProperty(name = "spring.cloud.nacos.config.enabled", matchIfMissing = true)
public class NacosConfigBootstrapConfiguration {

    @Bean
    @ConditionalOnMissingBean
    public NacosConfigProperties nacosConfigProperties() {
        return new NacosConfigProperties();
    }

    @Bean
    @ConditionalOnMissingBean
    public NacosConfigManager nacosConfigManager(
            NacosConfigProperties nacosConfigProperties) {
        return new NacosConfigManager(nacosConfigProperties);
    }

    @Bean
    public NacosPropertySourceLocator nacosPropertySourceLocator(
            NacosConfigManager nacosConfigManager) {
        return new NacosPropertySourceLocator(nacosConfigManager);
    }

}

自動裝配流程:


配置文件組裝源碼:

@Override
    public PropertySource<?> locate(Environment env) {
        nacosConfigProperties.setEnvironment(env);
        ConfigService configService = nacosConfigManager.getConfigService();

        if (null == configService) {
            log.warn("no instance of config service found, can't load config from nacos");
            return null;
        }
        long timeout = nacosConfigProperties.getTimeout();
        nacosPropertySourceBuilder = new NacosPropertySourceBuilder(configService,
                timeout);
        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);

        loadSharedConfiguration(composite);
        loadExtConfiguration(composite);
        loadApplicationConfiguration(composite, dataIdPrefix, nacosConfigProperties, env);

        return composite;
    }

加載應(yīng)用配置文件的順序源碼:

private void loadApplicationConfiguration(
            CompositePropertySource compositePropertySource, String dataIdPrefix,
            NacosConfigProperties properties, Environment environment) {
        String fileExtension = properties.getFileExtension();
        String nacosGroup = properties.getGroup();
        // load directly once by default
        loadNacosDataIfPresent(compositePropertySource, dataIdPrefix, nacosGroup,
                fileExtension, true);
        // 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
        for (String profile : environment.getActiveProfiles()) {
            String dataId = dataIdPrefix + SEP1 + profile + DOT + fileExtension;
            loadNacosDataIfPresent(compositePropertySource, dataId, nacosGroup,
                    fileExtension, true);
        }

    }

順序如下:

序號 說明
1 加載dataIdPrefix對應(yīng)的配置文件
2 加載dataIdPrefix.fileExtension對應(yīng)的配置文件
3 加載 dataIdPrefix-activeProfiles.fileExtension對應(yīng)的配置文件

2.1 NacosConfigAutoConfiguration

序號 說明
1 NacosConfigProperties nacos配置
2 NacosRefreshProperties 已經(jīng)不建議被使用
3 NacosRefreshHistory 刷新歷史
4 NacosConfigManager 配置
5 NacosContextRefresher 注冊nacos的監(jiān)聽器到應(yīng)用

2.2 NacosConfigEndpointAutoConfiguration

NacosConfigEndpoint

本地配置同步邏輯

    @ReadOperation
    public Map<String, Object> invoke() {
        Map<String, Object> result = new HashMap<>(16);
        result.put("NacosConfigProperties", properties);

        List<NacosPropertySource> all = NacosPropertySourceRepository.getAll();

        List<Map<String, Object>> sources = new ArrayList<>();
        for (NacosPropertySource ps : all) {
            Map<String, Object> source = new HashMap<>(16);
            source.put("dataId", ps.getDataId());
            source.put("lastSynced", dateFormat.get().format(ps.getTimestamp()));
            sources.add(source);
        }
        result.put("Sources", sources);
        result.put("RefreshHistory", refreshHistory.getRecords());

        return result;
    }

NacosConfigHealthIndicator

健康檢查 UP,DOWN,UNKNOWN ;

3 NacosConnectionFailureAnalyzer

連接不上nacos服務(wù)端拋出異常

@Override
    protected FailureAnalysis analyze(Throwable rootFailure,
            NacosConnectionFailureException cause) {
        return new FailureAnalysis(
                "Application failed to connect to Nacos server: \""
                        + cause.getServerAddr() + "\"",
                "Please check your Nacos server config", cause);
    }

小結(jié):服務(wù)通過集成該starter渗稍,通過http請求從nacos的服務(wù)端拉取配置數(shù)據(jù),并做了 配置刷新歷史团滥,注冊監(jiān)聽器到spring容器中竿屹, 本地緩存,和錯誤報告灸姊;

服務(wù)端封裝

源碼位置:https://github.com/alibaba/nacos/tree/develop/config

應(yīng)用啟動讀取配置文件整體調(diào)用鏈:待后續(xù)完成拱燃;

小結(jié)

如果讀完本篇文章你只能記住一句話:nacos作為配置中心可為單獨(dú)的服務(wù)提供外部化配置文件,也支持多應(yīng)用共享配置文件力惯。
從nacos的客戶端源碼分析中可看到一些配置優(yōu)先級的順序碗誉。

原創(chuàng)不易,關(guān)注誠可貴父晶,轉(zhuǎn)發(fā)價更高哮缺!轉(zhuǎn)載請注明出處,讓我們互通有無甲喝,共同進(jìn)步尝苇,歡迎溝通交流。
我會持續(xù)分享Java軟件編程知識和程序員發(fā)展職業(yè)之路埠胖,歡迎關(guān)注糠溜!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市直撤,隨后出現(xiàn)的幾起案子非竿,更是在濱河造成了極大的恐慌,老刑警劉巖谋竖,帶你破解...
    沈念sama閱讀 216,843評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件红柱,死亡現(xiàn)場離奇詭異侮东,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)豹芯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,538評論 3 392
  • 文/潘曉璐 我一進(jìn)店門悄雅,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人铁蹈,你說我怎么就攤上這事宽闲。” “怎么了握牧?”我有些...
    開封第一講書人閱讀 163,187評論 0 353
  • 文/不壞的土叔 我叫張陵容诬,是天一觀的道長。 經(jīng)常有香客問我沿腰,道長览徒,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,264評論 1 292
  • 正文 為了忘掉前任颂龙,我火速辦了婚禮习蓬,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘措嵌。我一直安慰自己躲叼,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,289評論 6 390
  • 文/花漫 我一把揭開白布企巢。 她就那樣靜靜地躺著枫慷,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浪规。 梳的紋絲不亂的頭發(fā)上或听,一...
    開封第一講書人閱讀 51,231評論 1 299
  • 那天,我揣著相機(jī)與錄音笋婿,去河邊找鬼誉裆。 笑死,一個胖子當(dāng)著我的面吹牛萌抵,可吹牛的內(nèi)容都是我干的找御。 我是一名探鬼主播,決...
    沈念sama閱讀 40,116評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼绍填,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了栖疑?” 一聲冷哼從身側(cè)響起讨永,我...
    開封第一講書人閱讀 38,945評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎遇革,沒想到半個月后卿闹,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體揭糕,經(jīng)...
    沈念sama閱讀 45,367評論 1 313
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,581評論 2 333
  • 正文 我和宋清朗相戀三年锻霎,在試婚紗的時候發(fā)現(xiàn)自己被綠了著角。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,754評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡旋恼,死狀恐怖吏口,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情冰更,我是刑警寧澤产徊,帶...
    沈念sama閱讀 35,458評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站蜀细,受9級特大地震影響舟铜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜奠衔,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,068評論 3 327
  • 文/蒙蒙 一谆刨、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧归斤,春花似錦痴荐、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,692評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至膝宁,卻和暖如春鸦难,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背员淫。 一陣腳步聲響...
    開封第一講書人閱讀 32,842評論 1 269
  • 我被黑心中介騙來泰國打工合蔽, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人介返。 一個月前我還...
    沈念sama閱讀 47,797評論 2 369
  • 正文 我出身青樓拴事,卻偏偏與公主長得像,于是被迫代替她去往敵國和親圣蝎。 傳聞我的和親對象是個殘疾皇子刃宵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,654評論 2 354