組態客戶端


在〈組態伺服器〉中,建立了一個簡單的組態伺服器,可以透過 HTTP 請求來取得組態資訊,若使用 Spring Boot,要建立一個消費組態資訊的客戶端相當簡單,若使用 Spring Tool Suite,建立專案時,可以選擇 Config Client,在這邊使用 Web 應用程式,來作為客戶端,因此 build.gradle 中會有以下相依:

...略
dependencies {
    implementation('org.springframework.boot:spring-boot-starter-web')
    implementation('org.springframework.cloud:spring-cloud-starter-config')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
}
...略

接著設置組態伺服器相關資訊,這可以在 resources 目錄中,建立一個 bootstrap.properties:

spring.application.name=gossip
spring.profiles.active=default
spring.cloud.config.uri=http://localhost:8888

bootstrap.properties 會在 application.properties 前載入,有些外部資源載入設定,放在兩者都可以,然而建議放在 bootstrap.properties,application.properties 留給本機應用程式的相關設定使用。

spring.application.name 為應用程式名稱,對應至組態伺服器的組態檔名稱,如果應用程式名稱與組態檔名稱不同,可以使用 spring.cloud.config.name 來設定,多個組態檔來源的話,可以用逗號區隔,spring.profiles.active 表示啟用哪個 Profile,spring.cloud.config.uri 為組態伺服器位址。

來寫個簡單的 REST 控制器:

package cc.openhome;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class TestController {
    @Value("${spring.datasource.username}")
    private String dbUser;

    @GetMapping("dbUser")
    public String dbUser() {
        return dbUser;
    }
}

這邊只是簡單地綁定一個組態設定,接著啟動組態伺服器以及目前的 Web 應用程式,請求 http://localhost:8080/dbUser,就會看到設定值,目前為止,若是組態伺服器上的設定更新了,這個應用程式沒辦法取得更新的資訊。

Spring Boot Actuator 是用來監控 Spring Boot 應用程式的方案,可以透過 REST 介面來提供監控服務,在這邊也可以藉用它來取得組態伺服器更新資訊,為了使用 Actuator,要在 build.gradle 後加入:

implementation('org.springframework.boot:spring-boot-starter-actuator')  

接著,必須開啟 refresh 介面以便被請求更新,這要加入 bootstrap.properties 中:

management.endpoints.web.exposure.include=refresh

對於想要能獲得更新資訊的元件,可以在上頭加註 @RefreshScope,例如:

package cc.openhome;

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;

@RestController
@RefreshScope
public class TestController {
    @Value("${spring.datasource.username}")
    private String dbUser;

    @GetMapping("dbUser")
    public String dbUser() {
        return dbUser;
    }
}

重新啟動 Web 應用程式,請求 http://localhost:8080/dbUser,首先你會看到既有的組態設定,接著修改組態伺服器上 spring.datasource.username 的值後,請求 http://localhost:8080/dbUser 的值仍是不變,可以用 POST 來請求 http://localhost:8080/actuator/refresh 來要求更新,例如透過 curl

>curl -X POST http://localhost:8080/actuator/refresh
["spring.datasource.username"]

重新請求 http://localhost:8080/dbUser,你就會看到更新的資訊了。

你可以在 configclt 中找到以上的範例專案。