<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 6480字,需瀏覽 13分鐘

           ·

          2021-07-13 23:07

          前言

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

          但是對于單體應(yīng)用的Spring Boot項(xiàng)目而言,動態(tài)刷新顯然是有點(diǎn)多余,反正就一個服務(wù),改下重啟不就行了?

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

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

          當(dāng)然以上列舉的兩種場景每個公司都有不同的解決方案,這里不做深究。

          微服務(wù)下有哪幾種主流的方案?

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

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

          1. Nacos:阿里巴巴的最近開源的項(xiàng)目,這個家伙很牛逼,一個干掉了Eureka(停更)和Config+Bus,既能作為配置中心也能作為注冊中心,并且有自己的獨(dú)立的 管理平臺,可以說是現(xiàn)在最主流的一種。

          2. Config+Bus:早期在用的微服務(wù)配置中心,可以依托GitHub管理微服務(wù)的配置文件,這種現(xiàn)在也是有不少企業(yè)在用,但是需要自己獨(dú)立部署一個微服務(wù),和Nacos相比遜色了不少。

          3. Apollo:攜程開源項(xiàng)目Apollo,這個也是不少企業(yè)在用,陳某了解的不多,有興趣的可以深入研究下。

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

          其實(shí)上述三種都可以在Spring Boot項(xiàng)目中適配,但是作為單體應(yīng)用有些重了,下面作者簡單的介紹兩種可用的方案。

          Spring Boot+Nacos(不推薦)

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

          當(dāng)然Nacos對Spring、Spring Boot 項(xiàng)目同樣適用。

          如何使用呢?這里作者只提供下思路,不做過多的深究,這篇在作者下個專欄Spring Cloud 進(jìn)階會詳細(xì)介紹:

          1. 下載對應(yīng)版本的Nacos,啟動項(xiàng)目,訪問http://localhost:8848進(jìn)入Nacos的管理界面;

          2. Spring Boot 項(xiàng)目引入Nacos的配置依賴nacos-config-spring-boot-starter,配置Nacos管理中心的地址。

          3. @NacosPropertySource、@NacosValue兩個注解結(jié)合完成。

          • @NacosPropertySource:指定配置中心的dataId,和是否自動刷新
          • @NacosValue替代@Value注解完成屬性的自動裝配
          1. 如果公司項(xiàng)目做了后臺管理,則可以直接調(diào)用Nacos開放的API修改對應(yīng)配置的值(替代了Nacos管理界面的手動操作),API的地址:https://nacos.io/zh-cn/docs/open-api.html

          此種方案雖說可以實(shí)現(xiàn)配置的動態(tài)刷新,但是還要集成Nacos,啟動一個Nacos的服務(wù),完全是有點(diǎn)大材小用了,實(shí)際項(xiàng)目中不推薦使用。

          Spring Boot+Config+actuator(推薦)

          此種方案實(shí)際使用的是Config配置中心,但是不像Nacos那般重,完全適用于單體應(yīng)用的SpringBoot項(xiàng)目,只需要做小部分的更改即可達(dá)到效果。

          方案一(不推薦)

          1. 添加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>
          1. 配置文件中暴露Spring Boot的端點(diǎn),如下:
          management.endpoints.web.exposure.include=*
          1. 配置文件中新增三個屬性配置:
          config.version=22
          config.app.name=dynamic-project
          config.platform=mysql
          1. 結(jié)合@RefreshScope注解動態(tài)刷新,寫個Controller,如下:
          @RestController
          //@RefreshScope該注解必須標(biāo)注,否則無法完成動態(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;
              }
          1. 啟動項(xiàng)目測試,瀏覽器訪問http://localhost:8080/show/version,返回信息如下圖:
          1. 修改target目錄下的配置文件,如下:
          config.version=33
          config.app.name=dynamic-project
          config.platform=ORACLE
          1. POST請求http://localhost:8080/actuator/refresh接口,手動刷新下配置(必須,否則不能自動刷新)

          2. 瀏覽器再次輸入http://localhost:8080/show/version,結(jié)果如下圖:

          可以看到,配置已經(jīng)自動修改了,結(jié)束。

          方案二(推薦)

          看到了方案一覺得如何?是不是有點(diǎn)雞肋了

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

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

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

          因此只需要在修改屬性之后調(diào)用下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);
                  //將修改后的配置設(shè)置到environment中
                  environment.getPropertySources().addFirst(propertySource);
                  //異步調(diào)用refresh方法,避免阻塞一直等待無響應(yīng)
                  new Thread(() -> contextRefresher.refresh()).start();
                  return "success";
              }

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

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

          調(diào)用refresh接口:http://localhost:8080/show/refresh重新設(shè)置屬性值;

          再次調(diào)用http://localhost:8080/show/version查看下配置是否修改了,如下圖:

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

          總結(jié)

          本文從微服務(wù)的配置中心介紹到Spring Boot 搭建簡易的配置中心,詳細(xì)介紹了幾種可行性的方案,作者強(qiáng)力推薦最后一種方案,簡化版的Config,完全適用于單體應(yīng)用。

          項(xiàng)目源碼地址:https://github.com/chenjiabing666/springboot-dynamic-config

          1. 還在用 Random生成隨機(jī)數(shù)了?試試 ThreadLocalRandom,好用!

          2. 系統(tǒng)設(shè)計題應(yīng)該怎么答才能得到架構(gòu)大佬的認(rèn)可

          3. 如何通過緩存來提升系統(tǒng)性能

          4. 重裝IDEA再也不愁了,一招搞定同步個人配置!

          最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊,覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點(diǎn)“在看”,關(guān)注公眾號并回復(fù) Java 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。

          謝謝支持喲 (*^__^*)

          瀏覽 85
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美一级黄色片子 | 亚洲无码三区 | 中文字幕三级小说 | 欧洲AV在线播放 | 日韩欧美手机在线观看 |