現現在咱們常常在討論服務端開發(主要是API服務)的時候談及「微服務」。微服務設計方法逐漸成爲了API開發的新業界標準。幾乎全部的組織都在推廣它。java
在這篇教程當中,咱們將探討而且完成一個叫作配置服務(Config Server)的微服務特性。全部微服務的可配置參數都在配置服務中寫入和維護。它更像是將屬性/資源文件從項目的代碼中統一抽離到一個外部服務,這樣的話若是某個屬性發生了改變,那麼使用它的服務並不須要從新部署。在不從新部署微服務的狀況下,全部的屬性改變將能夠體現出來。git
配置服務器的想法來自於12-factor app宣言。這份宣言與開發現代原生雲應用的最佳實踐指導相關。它建議將屬性/資源保存在服務器的環境當中。在這個環境裏,這些資源會在服務運行的時候發生變化——不一樣的配置一般在每一個環境當中有所不一樣。web
舉個例子,若是一個服務依賴與另外一個服務(因爲特定業務場景被調用),而且被依賴的服務的URL發生了改變,那麼咱們必須用新的地址構建和部署咱們的服務。可是若是咱們如今運用了12 factor app方法,而且從一個運行在不一樣進程裏的外部服務讀取配置,咱們就只須要刷新配置服務了。spring
因此,這個想法很是清晰以及有效。如今讓咱們來看看如何建立配置服務器。shell
咱們將使用基於spring-boot的spring-cloud API,它很是易於使用和流行。在spring framework的命名中,它被稱做Config Server。同時咱們也會經過git來託管屬性文件。數據庫
因此咱們最終用於這個demo的技術棧是:bootstrap
咱們首先將開發2個基於spring boot的微服務。windows
首先咱們經過給定的步驟構建配置服務器部分。瀏覽器
從spring boot初始化程序門戶開始,這是建立任何基於Spring Boot的應用的一個特別好的起點。在這裏咱們只會選用Config Server starter pom。經過使用此配置,只要咱們生成項目,就能夠下載一個zip文件,而後解壓縮後導入eclipse。 安全
一旦你從spring初始化器門戶得到了zip文件,咱們須要將它解壓縮到咱們選擇的目錄並將其做爲maven項目導入eclipse
下一步是選擇你喜歡的方式,從命令提示符或eclipse運行mvn clean install。
如今打開spring已經提供的Spring Application類,並在類以前添加@EnableConfigServer註解並再次構建項目。在使用這個註解以後,這個artifact將會表現得像一個spring配置服務器。
此類被添加這個註解以後看起來會像下面那樣——類名由你生成的項目名決定,固然你也能夠手動更改一個你喜歡的名稱。
package com.howtodoinjava.example.springconfigserver;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer
@SpringBootApplication
public class SpringConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringConfigServerApplication.class, args);
}
}
複製代碼
下一個很是重要的步驟是創建一個本地git倉庫。它能夠很輕鬆地經過在屬性文件裏配置URL被替換成遠程倉庫。咱們將放置被配置服務器微服務
使用的外部屬性文件來提供外部屬性配置。咱們須要跟着下面的步驟來建立一個本地git倉庫而且檢查樣例屬性文件。
首先請確保在你的機器上已經安裝了git shell,並且你能夠經過命令行運行git bash。能夠經過打開命令行,輸入git命令來確認。
在桌面建立一個目錄config-server-repo。
而後在config-server-repo目錄中建立一個文件config-server-client.properties
,並在文件中添加內容msg = Hello world - this is from config server
。
而後在config-server-repo目錄中建立一個文件config-server-client-development.properties
,並在文件中添加內容msg = Hello world - this is from config server - development environment
。
而後在config-server-repo目錄中建立一個文件config-server-client-production.properties
,並在文件中添加內容msg = Hello world - this is from config server - production environment
。
在這裏咱們爲不一樣的環境維護了一樣名稱的配置,由於咱們一般維護不一樣環境的屬性,如urls,credentials,數據庫詳細信息等。最重要的一點是咱們須要在每一個屬性文件中附加帶有環境名稱的連字符( - ),以便配置服務器理解它。此外,咱們須要使用咱們將在此以後建立的配置客戶端服務名稱命名屬性文件。
如今從config-server-repo目錄打開命令提示符並運行命令git init,使該目錄成爲git存儲庫。
運行git add。將全部內容添加到倉庫中。
最後咱們須要經過運行命令git commit -m「initial checkin」來提交屬性文件。下面是所有命令操做的截圖(譯者注:你也能夠用git bash操做。原做者使用的是windows命令行)。
在spring-config-sever項目的src\main\resources
目錄中建立一個名爲bootstrap.properties
的文件,並添加如下行。
#服務器端
server.port = 8888
#Git 倉庫地址。能夠替換成你本地git倉庫的絕對路徑
spring.cloud.config.server.git.uri=${USERPROFILE}\\Desktop\\config-server-repo
#關閉Management endpoint的安全檢驗
management.security.enabled=false
#譯者注,在springboot的2.x版本當中,
#management.security.enabled已經被廢棄。
#應該該成如下配置,才能夠訪問刷新配置的url /actuator/refresh
#management.endpoints.web.exposure.include=refresh
複製代碼
如今讓咱們瞭解這些屬性。
server.port
定義嵌入式服務器將啓動的端口spring.cloud.config.server.git.uri
將綁定git位置以查找配置。這裏咱們使用本地git倉庫,但只需更改此配置便可切換到遠程倉庫。management.security.enabled = false
將禁用/env,/refresh等上management endpoint的安全性。這是針對開發設置的,在生產環境當中應該啓用安全性。爲了確認服務器是否能夠識別這些屬性,咱們首先在項目根目錄運行如下命令:
java -jar target\spring-config-server-0.0.1-SNAPSHOT.jar
複製代碼
如今打開瀏覽器並檢查下面的Urls,它將返回JSON輸出。在propertySources
部分,咱們能夠看到咱們在屬性文件中添加的全部屬性內容。這確保配置服務器成功運行,它已識別git的位置,而且正在爲不一樣環境提供配置。
此外,咱們來看看在項目運行的時候,對屬性文件中的任何更改是否在服務器沒有從新啓動的狀況下生效——修改環境屬性文件當中的值,將它提交到git倉庫,而後經過查看對應環境的endponit(瀏覽器打開對應的url)來檢查配置是否在服務沒有重啓的狀況下生效——這就是配置服務器的魔法。
如今咱們將繼續進行客戶端實現。咱們將從一個單獨的微服務中獲取屬性。這是咱們的最終目標 - 將配置外部化到不一樣的服務。
打開https://start.spring.io/,並使用如下選定的依賴生成客戶端項目:
屏幕將以下所示。像Spring-Config-Server同樣,將生成的zip文件解壓縮到某個目錄並導入eclipse。
首先添加一個RestController以查看響應中的服務器端屬性值。爲此,打開已生成的@SpringBootApplication類文件,並在該文件的末尾添加一個該類。這很是簡單和直接,咱們僅僅只是在/message上暴露一個方法,用它返回由配置服務器微服務提供的msg屬性值。該配置服務器指向本地git倉庫(在生產環境它將會被替換爲一個遠程git倉庫)。
package com.howtodoinjava.example.springconfigclient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class SpringConfigClientApplication {
public static void main(String[] args) {
SpringApplication.run(SpringConfigClientApplication.class, args);
}
}
@RefreshScope
@RestController
class MessageRestController {
@Value("${msg:Hello world - Config Server is not working..pelase check}")
private String msg;
@RequestMapping("/msg")
String getMsg() {
return this.msg;
}
}
複製代碼
在src\main\resources目錄中建立一個名爲bootstrap.properties的文件,並添加如下屬性以及一些必需的配置與配置服務器鏈接。
spring.application.name=config-server-client
#Active Profile配置與環境有關。
#若是它爲空,則配置服務器將會使用末尾沒有環境變量的配置文件
#如 config-server-client.properties
spring.profiles.active=development
spring.cloud.config.uri=http://localhost:8888
management.security.enabled=false
複製代碼
上述主要的配置與配置服務器的配置意義一致。
讓咱們來測試配置服務器應用。
從spring-config-server文件夾打開命令行工具並運行mvn clean install命令。在構建完成以後,運行java -jar target\spring-config-server-0.0.1-SNAPSHOT.jar
配置服務器將會在本地的8888端口啓動。
一樣的, 從spring-config-clienet文件夾打開命令行工具並運行mvn clean install命令。在構建完成以後,運行java -jar target\spring-config-client-0.0.1-SNAPSHOT.jar
配置服務器將會在本地的8080端口啓動。
如今打開瀏覽器,經過訪問http://localhost:8080/msg
打開/msg
的rest endpoinit。它將會返回Hello world - this is from config server - Development environment
。它以前出如今config-server-client-development.properties
文件當中。
如今咱們將進行屬性更改並測試是否能夠在配置客戶端服務中反映,而無需從新啓動任何微服務。
對config-server-client-development.properties
中的msg
值進行更改而後提交到本地git,接着在瀏覽器中再次點擊http//localhost:8080/msg
,你將僅僅獲得舊值。
要得到新值,咱們須要經過從任意REST
客戶端使用POST
方法訪問http://localhost:8080/refresh
端點來刷新配置。
一旦配置客戶端服務被成功刷新後,新值就應該會出如今服務響應體中。這是由於Rest Controller暴露的@RefreshScope註解。
spring.application.name=config-server-client
須要保持一致,不然屬性將沒法被檢測到。git add/commit
命令來提交代碼到git倉庫。POST
方法訪問http://localhost:8080/refresh
來刷新配置客戶端服務。這就是建立配置服務器微服務的所有了。若是你有遇到任何的困難請在這篇文章的評論當中提出,咱們會很高興幫助你解決這些問題。
Happy Learning !!