Nacos系列:基于Nacos的配置中心

前言

在看正文之前,我想請(qǐng)你回顧一下自己待過(guò)的公司都是怎么管理配置的,我想應(yīng)該會(huì)有以下幾種方式:

1屿岂、硬編碼

沒(méi)有什么配置不配置的,直接寫在代碼里面鲸匿,比如使用常量類

優(yōu)勢(shì):對(duì)開發(fā)友好爷怀,開發(fā)清楚地知道代碼需要用到什么配置

劣勢(shì):涉及秘鑰等敏感配置直接暴露給開發(fā)人員,不安全带欢;如果想修改配置必須重新發(fā)版运授,比較麻煩

2、外部化配置文件

Spring項(xiàng)目經(jīng)常會(huì)在resoures目錄下放很多配置文件乔煞,各個(gè)環(huán)境對(duì)應(yīng)不同的配置文件吁朦,通過(guò)SVN管理

優(yōu)勢(shì):配置文件外部化,支持多環(huán)境配置管理渡贾,修改配置只需重啟服務(wù)逗宜,無(wú)需發(fā)版

劣勢(shì):系統(tǒng)龐大時(shí),配置文件很多空骚,多人開發(fā)纺讲,配置格式不統(tǒng)一,維護(hù)麻煩囤屹;敏感配置不需要暴露給開發(fā)人員熬甚,降低風(fēng)險(xiǎn),但開發(fā)經(jīng)常要和運(yùn)維溝通怎么修改配置肋坚,溝通不恰當(dāng)容易引發(fā)生產(chǎn)事故乡括;而且复局,如果應(yīng)用部署在多臺(tái)機(jī)器,對(duì)運(yùn)維來(lái)說(shuō)粟判,修改配置也是非常頭疼的事情(當(dāng)然也可以引入NFS系統(tǒng)來(lái)解決一部分問(wèn)題)

3亿昏、數(shù)據(jù)庫(kù)

配置信息存儲(chǔ)在數(shù)據(jù)庫(kù)中,靈活修改

優(yōu)勢(shì):可以靈活管理配置档礁,無(wú)需重啟服務(wù)

劣勢(shì):界面不友好角钩,配置沒(méi)有版本管理,一旦出現(xiàn)問(wèn)題呻澜,回滾或定位問(wèn)題都比較麻煩递礼;此外,數(shù)據(jù)庫(kù)必須要保證高可用羹幸,避免因此而造成生產(chǎn)故障

4脊髓、配置中心

微服務(wù)基礎(chǔ)架構(gòu)體系中的一個(gè)不可或缺的基礎(chǔ)組件

優(yōu)勢(shì):集中化管理,敏感配置可控栅受;多版本存儲(chǔ)将硝,方便追溯;界面友好屏镊,修改配置一鍵發(fā)布依疼;即使面對(duì)多集群也能從容應(yīng)對(duì),十分淡定

劣勢(shì):引入組件而芥,增加系統(tǒng)風(fēng)險(xiǎn)律罢;如果是中途切換成配置中心,也會(huì)增加研發(fā)接入成本棍丐;配置中心也需要保證高可用误辑,否則容易造成大面積影響

以上幾種管理配置文件的方式,我想都會(huì)有公司在用歌逢,不要因?yàn)榕渲弥行挠兄T多優(yōu)點(diǎn)巾钉,就盲目引進(jìn)項(xiàng)目中,我覺(jué)得應(yīng)該遵守以下兩個(gè)原則:

  • 做人做事趋翻,要知道自己幾斤幾兩

釋義:沒(méi)深入研究過(guò)的技術(shù)睛琳,就不要隨便拿到公司項(xiàng)目中來(lái)試水啦,恐怕到時(shí)候坑夠你填的踏烙,要不然就是你有信心玩得轉(zhuǎn)它师骗。

  • 殺只雞而已,你拿牛刀來(lái)做甚讨惩?

釋義:小團(tuán)隊(duì)小項(xiàng)目選擇簡(jiǎn)單的配置管理方式就好了辟癌,要什么配置中心,純屬?zèng)]事找事荐捻。

總而言之黍少,我們必須從實(shí)際出發(fā)寡夹,實(shí)事求是,選擇適合自己的技術(shù)棧厂置。

關(guān)于為什么需要有配置中心菩掏,我推薦一篇文章給你看,講得比較透徹:《微服務(wù)架構(gòu)為什么需要配置中心昵济?》

另外智绸,我覺(jué)得對(duì)開發(fā)本身來(lái)說(shuō),是寧愿自己管理自己代碼的配置的访忿,交給運(yùn)維總是會(huì)有各種各樣的問(wèn)題瞧栗,至于敏感配置,說(shuō)實(shí)話海铆,開發(fā)人員要真想做點(diǎn)“壞事”迹恐,那攔得住嗎?但是卧斟,從公司的角度來(lái)講殴边,把服務(wù)器的配置管理交給運(yùn)維同事是符合常理的,系統(tǒng)需要穩(wěn)定且安全地運(yùn)行唆涝,這是對(duì)客戶的負(fù)責(zé)找都,從這一方面去思考唇辨,這么做是合情合理的廊酣。

Okay,我就啰嗦到這里吧赏枚,下面正式介紹Nacos作為配置中心是怎么使用的亡驰。

Nacos 結(jié)合 Spring

添加 maven 依賴:

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-spring-context</artifactId>
    <version>${nacos-spring-context.version}</version>
</dependency>

使用 @EnableNacosConfig 開啟 Nacos Spring 的配置管理功能

@Configuration
@EnableNacosConfig(globalProperties = @NacosProperties(serverAddr = "127.0.0.1:8848"))
@NacosPropertySource(dataId = "nacos.spring.config", autoRefreshed = true)
public class NacosConfig {
}

其中:

@Configuration:Spring的注解,配置應(yīng)用上下文
@EnableNacosConfig:Nacos的注解饿幅,啟用 Nacos Spring 的配置管理服務(wù)
@NacosProperties:全局和自定義Nacos屬性的統(tǒng)一注解
@NacosPropertySource:加載數(shù)據(jù)源
globalProperties:全局 Nacos 屬性
serverAddr:Nacos Server服務(wù)器地址
dataId:配置的數(shù)據(jù)集ID
autoRefreshed:是否開啟配置動(dòng)態(tài)更新

再寫一個(gè)Controller類凡辱,來(lái)驗(yàn)證Nacos的配置管理功能,代碼如下:

package com.learn.nacos;

import com.alibaba.nacos.api.annotation.NacosInjected;
import com.alibaba.nacos.api.config.ConfigService;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.alibaba.nacos.api.exception.NacosException;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping(value = "config")
public class NacosConfigController {
     @NacosInjected
     private ConfigService configService;

     @NacosValue(value = "${useLocalCache:false}", autoRefreshed = true)
     private boolean useLocalCache;

     @RequestMapping(value = "/get", method = RequestMethod.GET)
     @ResponseBody
     public boolean get() {
         return useLocalCache;
     }

     @RequestMapping(method = RequestMethod.GET)
     @ResponseBody
     public ResponseEntity<String> publish(@RequestParam String dataId,
                                           @RequestParam(defaultValue = "DEFAULT_GROUP") String group,
                                           @RequestParam String content) throws NacosException {
         boolean result = configService.publishConfig(dataId, group, content);
         if (result) {
             return new ResponseEntity<String>("Success", HttpStatus.OK);
         }
         return new ResponseEntity<String>("Fail", HttpStatus.INTERNAL_SERVER_ERROR);
     }
}

該Controller類提供了兩個(gè)HTTP接口
讀取配置:http://127.0.0.1:8080/config/get
發(fā)布配置:http://127.0.0.1:8080/config?dataId=XXX&content=XXX

發(fā)布配置還可以通過(guò) Nacos Open API:curl -X POST "http://127.0.0.1:8848/nacos/v1/cs/configs?dataId=XXX&group=XXX&content=XXX 發(fā)布配置栗恩,你也可以用Postman工具模擬POST請(qǐng)求進(jìn)行配置發(fā)布透乾,我這里主要是為了方便驗(yàn)證問(wèn)題,采用了這種方式磕秤。

在驗(yàn)證之前乳乌,請(qǐng)先確保 Nacos Server 已經(jīng)啟動(dòng),Nacos Server 的安裝及啟動(dòng)方式詳見(jiàn):《Nacos系列:歡迎來(lái)到Nacos的世界市咆!》

啟動(dòng)Tomcat汉操,觀察Console控制臺(tái)

20:50:13.646 [RMI TCP Connection(5)-127.0.0.1] WARN com.alibaba.nacos.spring.core.env.AnnotationNacosPropertySourceBuilder - There is no content for NacosPropertySource from dataId[nacos.spring.config] , groupId[DEFAULT_GROUP] , properties[{encode=${nacos.encode:UTF-8}, namespace=${nacos.namespace:}, contextPath=${nacos.context-path:}, endpoint=${nacos.endpoint:}, serverAddr=${nacos.server-addr:}, secretKey=${nacos.secret-key:}, accessKey=${nacos.access-key:}, clusterName=${nacos.cluster-name:}}].

20:50:17.825 [RMI TCP Connection(5)-127.0.0.1] INFO com.alibaba.nacos.spring.context.event.LoggingNacosConfigMetadataEventListener - Nacos Config Metadata : dataId='nacos.spring.config', groupId='DEFAULT_GROUP', beanName='nacosConfig', bean='null', beanType='class com.learn.nacos.NacosConfig', annotatedElement='null', xmlResource='null', nacosProperties='{serverAddr=127.0.0.1:8848, encode=UTF-8}', nacosPropertiesAttributes='{encode=${nacos.encode:UTF-8}, namespace=${nacos.namespace:}, contextPath=${nacos.context-path:}, endpoint=${nacos.endpoint:}, serverAddr=${nacos.server-addr:}, secretKey=${nacos.secret-key:}, accessKey=${nacos.access-key:}, clusterName=${nacos.cluster-name:}}', source='org.springframework.core.type.classreading.AnnotationMetadataReadingVisitor@66e4d430', timestamp='1550753413647'

我們先通過(guò)http://127.0.0.1:8080/config?dataId=nacos.spring.config&content=useLocalCache=true發(fā)布一個(gè)dataId為nacos.spring.config且配置內(nèi)容為useLocalCache=true的配置集,觀察Nacos控制臺(tái)的變化

image

再通過(guò)http://127.0.0.1:8080/config/get讀取配置

image

然后在Nacos控制臺(tái)將useLocalCache的值改為false蒙兰,并發(fā)布配置

image
image
image

再次訪問(wèn)http://127.0.0.1:8080/config/get

image

Nacos 結(jié)合 Spring Boot

添加 Starter 依賴:

<dependency>
    <groupId>com.alibaba.boot</groupId>
    <artifactId>nacos-config-spring-boot-starter</artifactId>
    <version>0.2.1</version>
</dependency>

注意:版本 0.2.x.RELEASE 對(duì)應(yīng)的是 Spring Boot 2.x 版本磷瘤,版本 0.1.x.RELEASE 對(duì)應(yīng)的是 Spring Boot 1.x 版本芒篷。

application.properties中添加如下配置信息:

nacos.config.server-addr=127.0.0.1:8848

添加NacosConfigApplication啟動(dòng)類

@SpringBootApplication
@NacosPropertySource(dataId = "nacos.springboot.config", autoRefreshed = true)
public class NacosConfigApplication {
     public static void main(String[] args) {
         SpringApplication.run(NacosConfigApplication.class, args);
     }
}

如果你看過(guò)我的上一篇文章:《Nacos系列:基于Nacos的注冊(cè)中心》,那么你應(yīng)該知道 Spring Boot 實(shí)現(xiàn)方式和 Spring 的沒(méi)太大差別采缚,所以我就不再細(xì)說(shuō)了针炉,請(qǐng)參考我的示例源碼或者官網(wǎng)資料學(xué)習(xí)。

這里說(shuō)下我在學(xué)習(xí)過(guò)程中遇到的一個(gè)問(wèn)題扳抽,在application.properties添加配置文件的時(shí)候糊识,不小心將nacos.config.server-addr寫成了nacos.discovery.server-addr,結(jié)果啟動(dòng)項(xiàng)目時(shí)摔蓝,一直報(bào)錯(cuò):

ERROR 9028 --- [           main] o.s.b.d.LoggingFailureAnalysisReporter   : 

------

APPLICATION FAILED TO START

------

Description:

client error: invalid param. null

Action:

please check your client configuration

剛開始一直找不到原因赂苗,后面對(duì)著官網(wǎng)代碼示例復(fù)核,才發(fā)現(xiàn)是配置問(wèn)題導(dǎo)致的贮尉,呵呵噠拌滋,自己給自己挖坑。

后語(yǔ)

我挺喜歡Nacos的猜谚,既能做服務(wù)發(fā)現(xiàn)和管理败砂,又能做配置管理,這兩者本質(zhì)沒(méi)多大區(qū)別魏铅,Nacos把這兩者統(tǒng)一起來(lái)昌犹,一舉兩得,我覺(jué)得沒(méi)什么不好览芳,要不然你引入了Zookeeper作為注冊(cè)中心斜姥,還要引入Apollo作為配置中心,無(wú)端增加學(xué)習(xí)成本沧竟。就像之前聽(tīng)音樂(lè)铸敏,我一般用網(wǎng)易云音樂(lè)就好,后面因?yàn)楦懔税鏅?quán)的事悟泵,不得不下載了蝦米和QQ音樂(lè)杈笔,我就聽(tīng)個(gè)歌而已,手機(jī)里裝了三個(gè)APP糕非,你說(shuō)蒙具,這叫什么事兒?

示例源碼

  • Nacos + Springlearn-nacos-spring-config
  • Nacos + Spring Bootlearn-nacos-springboot-config

代碼已上傳至碼云Github上朽肥,歡迎下載學(xué)習(xí)

參考資料

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市鞠呈,隨后出現(xiàn)的幾起案子融师,更是在濱河造成了極大的恐慌,老刑警劉巖蚁吝,帶你破解...
    沈念sama閱讀 206,214評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件旱爆,死亡現(xiàn)場(chǎng)離奇詭異舀射,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)怀伦,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門脆烟,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人房待,你說(shuō)我怎么就攤上這事邢羔。” “怎么了桑孩?”我有些...
    開封第一講書人閱讀 152,543評(píng)論 0 341
  • 文/不壞的土叔 我叫張陵拜鹤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我流椒,道長(zhǎng)敏簿,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評(píng)論 1 279
  • 正文 為了忘掉前任宣虾,我火速辦了婚禮惯裕,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘绣硝。我一直安慰自己蜻势,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,224評(píng)論 5 371
  • 文/花漫 我一把揭開白布鹉胖。 她就那樣靜靜地躺著握玛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪次员。 梳的紋絲不亂的頭發(fā)上败许,一...
    開封第一講書人閱讀 49,007評(píng)論 1 284
  • 那天,我揣著相機(jī)與錄音淑蔚,去河邊找鬼。 笑死愕撰,一個(gè)胖子當(dāng)著我的面吹牛刹衫,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播搞挣,決...
    沈念sama閱讀 38,313評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼带迟,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了囱桨?” 一聲冷哼從身側(cè)響起仓犬,我...
    開封第一講書人閱讀 36,956評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎舍肠,沒(méi)想到半個(gè)月后搀继,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體窘面,經(jīng)...
    沈念sama閱讀 43,441評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,925評(píng)論 2 323
  • 正文 我和宋清朗相戀三年叽躯,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了财边。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,018評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡点骑,死狀恐怖酣难,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情黑滴,我是刑警寧澤憨募,帶...
    沈念sama閱讀 33,685評(píng)論 4 322
  • 正文 年R本政府宣布,位于F島的核電站袁辈,受9級(jí)特大地震影響馋嗜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜吵瞻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,234評(píng)論 3 307
  • 文/蒙蒙 一葛菇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧橡羞,春花似錦眯停、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至签夭,卻和暖如春齐邦,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背第租。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工措拇, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人慎宾。 一個(gè)月前我還...
    沈念sama閱讀 45,467評(píng)論 2 352
  • 正文 我出身青樓丐吓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親趟据。 傳聞我的和親對(duì)象是個(gè)殘疾皇子券犁,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,762評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容