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

煙花散盡13141發表於2021-06-15

背景

有多少次因為配置檔案忘記修改導致重新發布

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

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

有多少次因為配置導致專案啟動失敗!!!

配置服務中心

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>

原始碼

點我下載

相關文章