第4章 微服務太多,配置文件怎麼維護

目錄

4.1 初識分佈式配置

4.2 Spring Cloud Config

4.2.1 Config Server

4.2.2 Config Client

4.2.3 配置刷新

4.3 小結


在前面有提到,微服務系統是一種典型的分佈式系統,我們會將每個功能都儘可能地拆分一個可獨立部署、運行的服務,服務部署完成後,每一次請求的完成,都可能涉及到多個服務的協調作業,面對越來越多的微服務,我們需要有一個東西可以方便地管理配置文件、最好可以在一個地方管理所有微服務的配置,這個就是我們接下來要說的分佈式配置組件了。在接下來的內容中,簡稱這個分佈式配置組件爲配置中心。

4.1 初識分佈式配置

在開始介紹Spring Cloud的配置中心實現之前,我們可以先回憶下以前我們的系統配置是怎麼做的。

最開始學習的時候,很多東西都是沒有配置的,基本上都是硬編碼,簡單、快速,系統很快構建起來了,可是隨着系統的功能越來越複雜,代碼量越來越大,很多地方進行硬編碼已經不能滿足我們的需求,我們需要在不同的環境、不同的場景下通過修改配置項來達到不一樣的效果,配置項放在代碼裏面難找,而且修改起來會很麻煩。

於是,我們將可能頻繁變動的項目提出來放在了xml、properties文件中,方便修改,這個時候修改配置的時候已經不需要再去碰業務代碼,只要找到對應的配置文件,修改、打包、重新部署就可以了。這樣子看起來已經不錯了,但是隨着分佈式架構逐漸流行,一個一個的集羣被搭建起來,這個時候再給每個集羣實例搭配一個配置文件,維護的工作量就變得很大了。

這種情況運維人員一般都有一個config list,記錄了每個實例的配置文件放在哪裏、叫什麼名字、現在的配置項是什麼等等。這個清單如果維護出錯,對整個系統來說都會是一個災難。基於這種情況,分佈式系統需要一箇中心化的配置中心來替代這個config list,並且可以方便地從不同維度來進行配置,最好支持配置項的隨時,並且最好能夠實時生效。

4.2 Spring Cloud Config

Spring Cloud作爲一個完善的微服務框架,提供了Spring Cloud Config作爲推薦的分佈式配置組件。

Spring Cloud Config提供了服務端和客戶端,可以很好地支持分佈式系統的配置需求。使用服務端可以快速構建一個獨立於業務服務之外的配置中心,配置存儲默認使用git,因此它擁有git所擁有的一切優點。同時,它還原生支持使用Spring的Environment和PropertySource來獲取配置項。接下來,我們將使用Spring Cloud Config構建一個配置中心。

4.2.1 Config Server

新建Spring Boot工程,引入Spring Cloud Config的服務端maven依賴,爲了方便測試,我們同時引入了web和actuator的相關依賴。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>        

pom文件編寫完成後,在application.properties中添加配置信息如下:

spring.application.name=config-server
server.port=8888

# 配置git倉庫地址
# 這個地址是本書代碼所在git倉庫地址,這裏用到了倉庫中的book-config-repo目錄
spring.cloud.config.server.git.uri=https://github.com/hanbin/book

# 配置倉庫路徑
spring.cloud.config.server.git.search-paths=book-config-repo

# 去掉git權限校驗
spring.cloud.config.server.git.skip-ssl-validation=true

# 制定遠程倉庫中配置文件的customer name
spring.config.name=customer

最後,在啓動類中添加@EnableConfigServer註解開啓Spring Cloud Config的服務端功能,然後啓動即可。

我們在book-config-repo目錄下新建了配置文件:customer-dev.properties文件。我們可以通過customer-server服務提供的接口來訪問這個配置文件。

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

舉例來說,customer-dev.properties中的就是{application}-{profile}.properties的形式,customer即是應用名,profile通常用來標示不同的環境,label在使用git存儲時代表的是git的分支,不寫則默認爲master。

上面這些URI都可以獲取到遠程配置,可以看到使用上面格式的地址訪問可以看到如下內容:

http://localhost:8888/customer/dev
http://localhost:8888/customer/dev/master

通過上面兩個鏈接可以得到下面的結果:

{
    "name": "customer",
    "profiles": [
        "dev"
    ],
    "label": "master",
    "version": "97ffd82376b9ba87c5a1ffcf60b67eb4866f2415",
    "state": null,
    "propertySources": [
        {
            "name": "https://github.com/hanbin/book/book-config-repo/customer-dev.properties",
            "source": {
                "name": "icer123",
                "age": "1001"
            }
        }
    ]
}

通過其他格式接口可以直接獲取到的結果都是:

age: 1001
name: icer123

age和name就是我們需要的配置項。

構建完成配置中心後,接下來我們看看如何將微服務構建成爲“配置中心客戶端”,來獲取配置中心的配置項。

4.2.2 Config Client

前面我們創建了customer服務,這節我們會將customer服務作爲config-server的client,通過遠程獲取的方式拿到customer-dev.properties中的配置項。

在開始之前,這裏要提到一個新的endpoint:env。env端點主要用來顯示服務的配置信息。在Spring
Boot2中,env端點默認是關閉的。通過添加下面的代碼到application.properties中,可以讓env端點能夠被訪問。

management.endpoints.web.exposure.include=health,info,env

在瀏覽器中可以看到如圖4.1所示的頁面。

 

641684178b7634a02b7f30b7bc56d276.png
圖4.1 通過瀏覽器查看env端點

 

爲customer工程添加Spring Cloud Config的支持,需要在pom.xml文件中添加下面的代碼。

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-config</artifactId>
</dependency>

啓動項目,可以在啓動日誌中看到如圖4.2所示的內容。

846577e69b6587ce46c18004ff2dc0b8.png

圖4.2 微服務啓動過程中加載遠程配置中心

 

可以看到,添加了Spring Cloud Config的依賴後,項目在啓動過程中會默認向http://localhost:8888請求遠程配置,附帶的參數name爲項目的spring.application.name,profiles爲default,label爲null。

這裏的默認配置不能拿到任何信息,因爲profiles傳的不對,在customer工程的application.properties配置文件中添加。

spring.cloud.config.uri=http://localhost:8888
spring.cloud.config.name=customer
spring.cloud.config.profile=dev

重新啓動程序,可以看到如圖4.3所示的啓動日誌。

圖4.3 自定義config配置後的啓動日誌

 

通過圖4.4可以看到現在customer在啓動時讀取到了之前我們在config server中的配置文件customer-dev.properties。通過本節最開始打開的env端點可以查看,如圖4.4所示。

 

圖4.4 微服務成功讀取到遠程配置文件

 

這裏有兩個配置文件需要注意下:spring.application.name 和 spring.cloud.config.name。

spring.application.name一般配置的是微服務的實例名,這個名字是微服務之間調用時候的唯一名稱。spring.cloud.config.name配置的是Spring Cloud Config中涉及的application名稱,在本節的例子中,對應的就是customer。如果去掉spring.cloud.config.name這個配置項,Spring Cloud Config會使用spring.application.name的配置去配置中心取值。

注意:充分使用label,profile可以完美達到一套代碼部署在多個環境,僅通過在啓動參數中修改label和profile就將各個環境進行區分的目的。

4.2.3 配置刷新

前面講的都是在系統啓動之前添加配置,那麼在系統運行過程中,能否“熱刷新”,讓配置項在運行期可以被直接改動。

Spring Cloud Config是支持“熱刷新”的,這裏需要用到refresh端點。

還是以customer工程爲例。爲了方便測試,我們將application.properties中的:

management.endpoints.web.exposure.include=health,info,env

換成:

management.endpoints.web.exposure.include=*

這樣,customer的所有端口就已經全部被放開了。

我們新建UserController.java文件,文件內容如下:

package cn.com.hanbinit.customer.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RefreshScope
@RestController
public class UserController {

    @Value("${name}")
    private String name;

    @Value("${age}")
    private Long age;

    @GetMapping("/showinfo")
    public String showNameAndAge(){
        return "name: " + name + ", age: " + age;
    }

}

上面代碼中@RefreshScope註解是實現變量熱加載的必需配置。@Value可以獲取到配置文件以及環境變量中的配置。上面代碼中的name和age就分別對應了配置文件中的name和age。showinfo接口返回了@Value獲取到的屬性值。

啓動項目,訪問http://localhost:8001/showinfo接口,可以看到如圖4.5的返回。

 

圖4.5 通過showinfo接口打印配置項的值

 

接下來,我們將customer-dev.properties
中的icer改爲icer123,100改爲1001,push到遠程倉庫。通過postman工具調用refresh端點,如圖4.6所示。

圖4.6 調用refresh端點,刷新name和age的值


 

這個時候,刷新showinfo的調用頁面,可以看到如圖4.7的結果。

圖4.7 調用refresh端點後showinfo接口的返回

 

這裏,就說明我們的熱加載已經成功。

注意:這種刷新方式僅適用於非初始化對象的情況下,如果配置項需要在系統啓動的時候加載並且使用。那麼在這裏使用refresh端點是不會生效的。配置項即使刷新過去,但是確沒有能真正生效。

截止到這裏,我們已經可以通過Spring Cloud Config搭建遠程的配置中心,並且可以讓微服務獲取到配置中心的配置項,且可以通過refresh端點達到熱加載的目的。那麼能不能實現自動刷新呢?手動調用refresh端點還是比較麻煩的。自動刷新當然是可以的,自動刷新後面有機會再寫。

4.3 小結

本章我們使用Spring Cloud Config創建了配置中心,並對之前的customer微服務進行了改造,讓customer服務可以遠程獲取到配置中心的配置。

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