【springcloud長文系列】不要每天重複修改配置了,試試config一處修改病毒式蔓延自動更新配置吧|智能化開發


背景

有多少次因爲配置文件忘記修改導致重新發布

有多少次因爲無法實時修改配置導致重新發布

有多少次同一個配置在不同項目需要重複修改

有多少次因爲配置導致項目啓動失敗!!!

配置服務中心

config官網文檔

  • 面對上面種種的問題springcloud爲我們提供一種解決方案---Springcloud Config它爲分佈式微服務提供了集中化的外部配置支持,配置服務器爲微服務下所有環境提供配置中心
  • Springcloud Config分爲服務端和客戶端、服務端就是本節介紹的對象。而客戶端就是嵌入在各個微服務中和服務端進行交互的從而實現配置的動態獲取

image-20210601185249248

pom

  • 還是一樣的味道我們通過framework-root框架來實現我們config中心,首先繼承framework-root然後在pom中添加如下座標
<dependency>
    <groupid>org.springframework.cloud</groupid>
    <artifactid>spring-cloud-config-server</artifactid>
</dependency>

application.yml

  • 除了一些基本的參數設定以外我們需要指定config拉取的倉庫即git相關信息
server:
  port: 8070
spring:
  application:
    name: config-server
  cloud.config.server.git:
    uri: https://gitee.com/zxhTom/spring-cloud-demo
    searchPaths: helloworldconfig

啓動類

@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class,args);
    }
}

測試

  • 你沒看錯!就是這簡單或者說還是之前的配方。我們只需要引包、配置、啓動即可!這就是spring的強大之處或者說是springboot的開箱即用的強大之處
  • 我們訪問http://localhost:8070/master/config-server-dev.properties就會將https://gitee.com/zxhTom/spring-cloud-demo項目下master分支下的helloworldconfig文件夾下的config-server-dev.properties文件讀取出來!
  • 請注意下,筆者的config倉庫後續會有變動。最終讀者的演示情況和筆者這裏略有不同!!!

image-20210601191840200

路徑規則

  • 上面我們已經可以通過接口的形式訪問到我們的配置文件了。但是那只是其中一種方式我們換個接口同樣可以訪問到http://localhost:8070/config-server-dev.yml 。那麼config的代理訪問肯定是按照一定規律來的。我們訪問官網,官網已經幫我們整理好了
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
  • 咋一看,心裏萬馬奔騰這是啥玩意呀。再仔細看看你會發現官網總結的太到位了。首先官網整理出的是三種訪問格式:resultfulymlproperties 。當我們的接口滿足其中一種格式的時候就會被config解析出來並有對應變量管理。

image-20210602164423275

  • 爲了充分演示出效果,小哲這裏新建了幾個配置文件。當我們訪問如下接口時會出現哪幾種情況http://localhost:8070/config/server-dev .
  • 按照我們上面的格式進行匹配,首先是resultful結構的,那麼就只有一種匹配方式得出application=config;profile=server-dev,label=null。label是可填的默認是master。

image-20210602164749382

  • 最終我們可以看到我們分析是沒有問題,其中多處一個version字段,這個筆者猜測是git commitId,因爲我發現和提交記錄一樣。 而對應的配置文件就是propertySources裏的文件。細心的朋友一定會發現這裏爲什麼是個數組呢?這裏筆者在官網上沒有找到說明但是經過測試筆者這裏整理出springcloud config映射規則
//後綴包括兩種 。 回去找{label}分支下如下格式的文件
{application}/{profile}.[properties|yml]
{application}.[properties|yml]
  • 另外兩種方式和resultful差不多,只不過他返回的信息時精簡版的。只返回配置文件中內容的並集。這裏需要注意相同內容取前者,那麼誰先誰後呢?這就需要我們resultful格式接口告訴我們了。

image-20210603093037737

  • 記住這個時候我們訪問http://localhost:8070/config-server.properties 。 然後通過resultful風格來確定是來源哪裏.這裏在強調下上面hello爲什麼是yml 。還記得上面我提到在這麼多文件中如果存在相同的配置會優先去首位的。這是什麼意思呢?
  • 我們通過resultful可以看出來會讀取三個文件的配置分別是config-server.propertiesconfig-server.ymlconfig.properties

image-20210603094036785

  • 我們在分別看下這三個文件中的內容,hello這個key出現在兩個文件中。然後在resultful接口我們可以看出config-server.yml排在config.properties前面,所以我們通過文件後綴方式訪問到的數據配置hello=yml

配置讀取客戶端

  • 上面我們也提到了關於config存在兩個角色,config中心是用來統一爲微服務提供服務的,剩下的就是嵌入在微服務中的。在配置微服務的config客戶端之前我們先來梳理下springboot的一個注意點。
  • springboot的配置文件除了在加載順序有不同之外,還有一點是文件名的區別。在springboot中其實存在兩種配置文件名稱;我們常用的是application開頭的配置文件(application.ymlapplication.properties)。
  • springcloud程序會創建一個bootstrap上下文同時他也是application上下文的父類!它負責從外部源加載配置屬性,並解密本地外部配置文件中的屬性。這兩個上下文共享一個Environment,它是任何Spring應用程序的外部屬性的來源。在springcloud中bootstrap類型的配置文件優先級最高所以不需要擔心會被本地的配置所覆蓋。
  • 我們客戶端想要讀取config-server中心的配置數據我們就需要在bootstrap配置文件中配置。

bootstrap.yml

zxhtom: hello-zxhtom
spring:
  cloud:
    config:
      label: master
      name: config-server
      profile: dev    //這裏和config-server解析不一樣的是,他將訪問master分支下的config-server-dev.yml或者properties文件
      uri: http://localhost:8070

application.yml

zxhtom: hello-zxhtom2
server:
  port: 80
  tomcat:
    max-threads: 10

pom

<dependency>
    <groupid>org.springframework.cloud</groupid>
    <artifactid>spring-cloud-starter-config</artifactid>
</dependency>

測試

  • 首先引入pom包這裏大家應該都沒有問題,其次我們在application.ymlbootstrap.yml兩個配置文件中配置相同的東西。這個時候在bootstrap中不配置config東西。此時我們訪問zxhtom參數得到的結果是application中的。當我們將config配置加進來之後我們訪問到的是git遠程倉庫的東西。關於演示筆者這裏就不演示了。因爲上面配置完成之後我們只需要寫個接口獲取參數就可以了。

小瑕疵

  • 但是存在一個小瑕疵,當我們遠程倉庫配置修改後我們的服務也需要跟着修改!這好坑啊,感情玩了半天我還在原地打轉啊。除了解決多模塊相同配置重複修改的問題,重啓的問題還是沒能解決。難道我們就只能如此了嗎?

  • 上面我們已經實現config-server來讀取遠程倉庫配置了。也實現了客戶端通過config-server讀取遠程配置了。但是當我們修改git遠程倉庫上配置時,我們的config-server會實時的修改配置值,客戶端確無法實時更新!解決辦法就是重啓。

動態刷新

  • 發現問題才能不斷進步當然前提你得承認問題!這是一個偉大的哲學家說的(我自己) 。
  • 首先我們需要引入actuator模塊,這個我們在講解hystrix模塊的時候在父項目root中引入了。當時筆者一直出了在高版本中actuator中需要加入actuator前綴。
  • 然後我們在獲取配置的接口類上添加@RefreshScope 。 記住這裏一定要在這裏加哦!!!
  • 好了,到這裏我們就解決了,現在啓動我們的config客戶端,在這裏我們是order模塊。啓動之後通過http://localhost/order/config/getConfig獲取zxhtom這個值。

image-20210603160303384

仍然不足

  • 上面我們基於actuator實現了動態刷新,但是這個動態刷新並不是自動刷新還是需要我們認爲參與。實際項目生產使用中會有很多個微服務充電config-client角色。那麼我們每次更新git倉庫內容時是不是需要誒個調用接口呢?這顯然是不行的。我也說了存在問題才能優化。那麼我們該如何解決

奇技淫巧

脫離git

  • config-server中我們通過spring.cloud.config.server.git.uri中指定git遠程倉庫。如果我們在內網環境開發而且內網中我們沒有自己搭建git服務呢。我們可以配置本地地址也可以實現讀取指定外部倉庫的。
spring.cloud.config.server.git.uri=file://xxxxxx/repository	

多倉庫

spring.cloud.config.server.git:
  uri: https://gitee.com/zxhTom/spring-cloud-demo
  searchPaths: helloworldconfig
  repos:
    dev:
      pattern: dev/*
      uri: file:///D:\test\repository\spring-cloud-demo
      searchPaths: helloworldconfig
  • 上述配置spring.cloud.config.server.git.uri是默認的倉庫配置。然後根據repos來進行多倉庫的配置。repos下跟了多少個就說明是多少個環境配置。比如我們上面的配置repos下只有dev一個配置,這個dev就是我們用於dev的環境。他的匹配模式是任何已dev開頭的都將使用dev這個配置的倉庫來進行我們上面匹配規則分析。

image-20210603133519473

添加權限

  • 如果你的公司沒有單獨部署git。如果你使用的就是github這種公網性質。那麼將我們項目中的配置放在這種地方是不是有點不安全呢?你的所有的服務的密碼都被公開了。這樣是極度不安全。那麼我們要麼自己單獨部署git。要麼將配置文件這個項目設置成私有

  • 項目配置成私有我們config-server所在的服務可以通過ssh方式進行配置項目uri 。

  • spring: 
      cloud: 
        config: 
          server: 
            git: 
              username: xxxx
              password: xxxx	
    
  • 我們也可以通過如上配置方式將我們項目的用戶名和密碼配置,然後在通過http方式進行訪問。這樣也是可以的。

指定本地倉庫位置

  • 當我們通過接口訪問獲取遠程倉庫配置信息的時候,實際上config幫我們將遠程倉庫的文件拉取到本地路徑上了。這個我們通過觀察日誌就可以看得出來。

image-20210603134926335

  • 可以證實我們沒訪問一次接口config都會刷新本地文件庫的。但是本地文件存儲的位置其實是不固定的,項目每次啓動當前項目所在的目錄都會發生隨機改變。文件路徑爲config-repo-隨機id 。會出現這麼一種情況當我們重啓的時候git掛了這個時候我們將無法獲取但是因爲隨機id的原因我們將獲取不到配置信息了。所以config` 可以讓我們指定這個路勁。
spring.cloud.config.server.git.basedir: xxxxx	

分模塊讀取配置

  • 實際分佈式項目中我們會有很多模塊,如果我們都將放在同一層級的話會顯得很多。這用並不是不能使用但是爲了方便管理我們還是希望能夠進行分類管理不同的服務請求過來進不同文件中進行匹配。
spring.cloud.config.server.git.searchPaths: '{application}'
  • 而application就是我們上文提到的通過地址分析中得到的那個application 。注意這裏一定要加引號

image-20210603141838254

總結

  • springcloud config模塊極大的簡化了我們微服務中重複配置的問題,默認使用的git來實現公共服務的獲取的當然他也是支持svn,關於svn的整合呢筆者這裏沒有指出因爲現在使用svn的公司應該很少了。如果非要使用svn的話也很簡單。將uri地址換成svn的就可以了。前提引入如下包
<dependency>
  <groupid>org.tmatesoft.svnkit</groupid>
  <artifactid>svnkit</artifactid>
  <version>1.8.10</version>
</dependency>

源碼

點我下載

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章