如何讓 Spring Boot 的配置 “動” 起來?

前言

對于微服務而言配置本地化是個很大的雞肋胡嘿,不可能每次需要改個配置都要重新把服務重新啟動一遍,因此最終的解決方案都是將配置外部化钳踊,托管在一個平臺上達到不用重啟服務即可一次修改多處生效的目的衷敌。

但是對于單體應用的Spring Boot項目而言,動態(tài)刷新顯然是有點多余拓瞪,反正就一個服務缴罗,改下重啟不就行了?

然而在某些特殊的場景下還是必須用到動態(tài)刷新的祭埂,如下:

  1. 添加數(shù)據(jù)源:對接某個第三方平臺的時候面氓,你不可能每次添加一個數(shù)據(jù)源都要重啟下服務
  2. 固化的對接:大量的固定對接方式,只是其中的某個固定的代碼段不同蛆橡,比如提供視圖中的字段不同舌界,接口服務中字段不同等情況。

當然以上列舉的兩種場景每個公司都有不同的解決方案泰演,這里不做深究呻拌。

微服務下有哪幾種主流的方案?

微服務下的動態(tài)配置中心有三種主流的方式睦焕,如下圖:


image.png

上圖中的三種配置中心方案可以說是現(xiàn)在企業(yè)中使用率最高的藐握,分別是:

  1. Nacos:阿里巴巴的最近開源的項目,這個家伙很牛逼垃喊,一個干掉了Eureka(停更)和Config+Bus猾普,既能作為配置中心也能作為注冊中心,并且有自己的獨立的 管理平臺本谜,可以說是現(xiàn)在最主流的一種初家。
  2. Config+Bus:早期在用的微服務配置中心,可以依托GitHub管理微服務的配置文件耕突,這種現(xiàn)在也是有不少企業(yè)在用笤成,但是需要自己獨立部署一個微服務,和Nacos相比遜色了不少眷茁。
  3. Apollo:攜程開源項目Apollo炕泳,這個也是不少企業(yè)在用,陳某了解得不多上祈,有興趣的可以深入研究下培遵。

針對Spring Boot 適用的幾種方案浙芙?

其實上述三種都可以在Spring Boot項目中適配,但是作為單體應用有些重了籽腕,下面作者簡單的介紹兩種可用的方案嗡呼。

Spring Boot+Nacos(不推薦)

不得不說阿里巴巴確實挺有野心,阿里要做的其實是一個微服務生態(tài)皇耗,Nacos不僅僅可以作為Spring Cloud的配置和注冊中心南窗,也適配了Dubbo、K8s郎楼,官方文檔中對于如何適配都做了詳細的介紹万伤,作者 這里就不再詳細介紹了,如下圖:

image.png

當然Nacos對Spring呜袁、Spring Boot 項目同樣適用敌买。

如何使用呢?這里作者只提供下思路阶界,不做過多的深究:

  1. 下載對應版本的Nacos虹钮,啟動項目,訪問http://localhost:8848進入Nacos的管理界面膘融;
  2. Spring Boot 項目引入Nacos的配置依賴nacos-config-spring-boot-starter芙粱,配置Nacos管理中心的地址。
  3. @NacosPropertySource托启、@NacosValue兩個注解結合完成宅倒。
  • @NacosPropertySource:指定配置中心的dataId,和是否自動刷新
  • @NacosValue替代@Value注解完成屬性的自動裝配
  1. 如果公司項目做了后臺管理屯耸,則可以直接調用Nacos開放的API修改對應配置的值(替代了Nacos管理界面的手動操作),API的地址:nacos.io/zh-cn/docs/…

此種方案雖說可以實現(xiàn)配置的動態(tài)刷新蹭劈,但是還要集成Nacos疗绣,啟動一個Nacos的服務,完全是有點大材小用了铺韧,實際項目中不推薦使用多矮。

Spring Boot+Config+actuator(推薦)

此種方案實際使用的是Config配置中心,但是不像Nacos那般重哈打,完全適用于單體應用的SpringBoot項目塔逃,只需要做小部分的更改即可達到效果。

方案一(不推薦)

  • 添加Config的依賴料仗,如下:
<!-- springCloud的依賴-->
<dependencyManagement>
    <dependencies>
        <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Hoxton.SR3</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
    </dependencies>
</dependencyManagement>

<!-- config的依賴-->
<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-config</artifactId>
    </dependency>

  <!-- actuator的依賴-->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-actuator</artifactId>
    </dependency>
  • 配置文件中暴露Spring Boot的端點湾盗,如下:
management.endpoints.web.exposure.include=*
  • 配置文件中新增三個屬性配置:
config.version=22
config.app.name=dynamic-project
config.platform=mysql
  • 結合@RefreshScope注解動態(tài)刷新,寫個Controller立轧,如下:
@RestController
//@RefreshScope該注解必須標注格粪,否則無法完成動態(tài)更新
@RefreshScope
public class DynamicConfigController {
    @Value("${config.version}")
    private String version;

    @Value("${config.app.name}")
    private String appName;

    @Value("${config.platform}")
    private String platform;

    @GetMapping("/show/version")
    public String test(){
        return "version="+version+"-appName="+appName+"-platform="+platform;
    }
image.png
  • 修改target目錄下的配置文件帐萎,如下:
config.version=33
config.app.name=dynamic-project
config.platform=ORACLE
image.png

可以看到赁项,配置已經自動修改了,結束澈段。

方案二(推薦)

看到了方案一覺得如何悠菜?是不是有點雞肋了

第一個問題:為什么還要調用一次手動刷新呢?

第二個問題:只能手動地在配置文件中改嗎均蜜?如果想在后臺管理系統(tǒng)該怎么辦李剖?

想要解決上述兩個問題還是要看下Config的源碼,代碼關鍵部分在org.springframework.cloud.context.refresh.ContextRefresher#refresh()方法中囤耳,如下圖:

image.png

因此只需要在修改屬性之后調用下ContextRefresher#refresh()(異步篙顺,避免一直阻塞等待)方法即可。

為了方便測試充择,我們自己手動寫一個refresh接口德玫,如下:

@GetMapping("/show/refresh")
    public String refresh(){
        //修改配置文件中屬性
        HashMap<String, Object> map = new HashMap<>();
        map.put("config.version",99);
        map.put("config.app.name","appName");
        map.put("config.platform","ORACLE");
        MapPropertySource propertySource=new MapPropertySource("dynamic",map);
        //將修改后的配置設置到environment中
        environment.getPropertySources().addFirst(propertySource);
        //異步調用refresh方法,避免阻塞一直等待無響應
        new Thread(() -> contextRefresher.refresh()).start();
        return "success";
    }

上述代碼中作者只是手動設置了配置文件中的值椎麦,實際項目中可以通過持久化的方式從數(shù)據(jù)庫中讀取配置刷新宰僧。

下面我們測試看看,啟動項目观挎,訪問http://localhost:8080/show/version琴儿,發(fā)現(xiàn)是之前配置在application.properties中的值,如下圖:

image.png

調用refresh接口:http://localhost:8080/show/refresh重新設置屬性值嘁捷;

再次調用http://localhost:8080/show/version查看下配置是否修改了造成,如下圖:

image.png

從上圖可以發(fā)現(xiàn),配置果然修改了雄嚣,達到了動態(tài)刷新的效果晒屎。

總結

本文從微服務的配置中心介紹到Spring Boot 搭建簡易的配置中心,詳細介紹了幾種可行性的方案缓升,作者強力推薦最后一種方案鼓鲁,簡化版的Config,完全適用于單體應用港谊。

作者:碼猿技術專欄
原文鏈接:https://juejin.cn/post/6977169384787673096

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末骇吭,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子封锉,更是在濱河造成了極大的恐慌绵跷,老刑警劉巖膘螟,帶你破解...
    沈念sama閱讀 211,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異碾局,居然都是意外死亡荆残,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,347評論 3 385
  • 文/潘曉璐 我一進店門净当,熙熙樓的掌柜王于貴愁眉苦臉地迎上來内斯,“玉大人,你說我怎么就攤上這事像啼》常” “怎么了?”我有些...
    開封第一講書人閱讀 157,435評論 0 348
  • 文/不壞的土叔 我叫張陵忽冻,是天一觀的道長真朗。 經常有香客問我,道長僧诚,這世上最難降的妖魔是什么遮婶? 我笑而不...
    開封第一講書人閱讀 56,509評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮湖笨,結果婚禮上旗扑,老公的妹妹穿的比我還像新娘。我一直安慰自己慈省,他們只是感情好臀防,可當我...
    茶點故事閱讀 65,611評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著边败,像睡著了一般袱衷。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上笑窜,一...
    開封第一講書人閱讀 49,837評論 1 290
  • 那天祟昭,我揣著相機與錄音,去河邊找鬼怖侦。 笑死,一個胖子當著我的面吹牛谜叹,可吹牛的內容都是我干的匾寝。 我是一名探鬼主播,決...
    沈念sama閱讀 38,987評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼荷腊,長吁一口氣:“原來是場噩夢啊……” “哼艳悔!你這毒婦竟也來了?” 一聲冷哼從身側響起女仰,我...
    開封第一講書人閱讀 37,730評論 0 267
  • 序言:老撾萬榮一對情侶失蹤猜年,失蹤者是張志新(化名)和其女友劉穎抡锈,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體乔外,經...
    沈念sama閱讀 44,194評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡床三,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 36,525評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了杨幼。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片撇簿。...
    茶點故事閱讀 38,664評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖差购,靈堂內的尸體忽然破棺而出四瘫,到底是詐尸還是另有隱情,我是刑警寧澤欲逃,帶...
    沈念sama閱讀 34,334評論 4 330
  • 正文 年R本政府宣布找蜜,位于F島的核電站,受9級特大地震影響稳析,放射性物質發(fā)生泄漏洗做。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,944評論 3 313
  • 文/蒙蒙 一迈着、第九天 我趴在偏房一處隱蔽的房頂上張望竭望。 院中可真熱鬧,春花似錦裕菠、人聲如沸咬清。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,764評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽旧烧。三九已至,卻和暖如春画髓,著一層夾襖步出監(jiān)牢的瞬間掘剪,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,997評論 1 266
  • 我被黑心中介騙來泰國打工奈虾, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留夺谁,地道東北人。 一個月前我還...
    沈念sama閱讀 46,389評論 2 360
  • 正文 我出身青樓肉微,卻偏偏與公主長得像匾鸥,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子碉纳,可洞房花燭夜當晚...
    茶點故事閱讀 43,554評論 2 349

推薦閱讀更多精彩內容