分散式配置中心spingcloud-config-server
原文地址:
分散式配置中心spingcloud-config-server
分散式配置中心我的專案早就在使用了,是我一個同事搭建的,對於這個,我只是瞭解一點。所以抽空自己搭建了一個,其中也發現了不少問題。所以寫了這篇文章記錄一下搭建過程!相信跟著我寫的步驟,,大部分人應該可以搭建成功的!通過這篇文章後,你也可以學會單機、叢集下實現應用的熱部署
簡介
Spring Cloud Config為分散式系統中的外部化配置提供伺服器和客戶端支援。使用Config Server,您可以在所有環境中管理應用程式的外部屬性。客戶端和伺服器對映的概念與Spring Environment和PropertySource抽象相同,因此它們與Spring應用程式非常契合,但可以與任何以任何語言執行的應用程式一起使用。隨著應用程式通過從開發人員到測試和生產的部署流程,您可以管理這些環境之間的配置,並確定應用程式具有遷移時需要執行的一切。伺服器儲存後端的預設實現使用git,因此它輕鬆支援標籤版本的配置環境,以及可以訪問用於管理內容的各種工具。可以輕鬆新增替代實現,並使用Spring配置將其插入。
以上簡介來自springcloud的中文文件
配置中心倉庫搭建
這裡我們使用github作為我們的配置檔案倉庫。
-
現在github上建立一個倉庫,我的倉庫名叫springcloud-config-server-repo
-
將倉庫克隆到本地
-
在倉庫下新建一個目錄,叫config-server-client,裡面放三個配置檔案
config-server-client-dev.yml config-server-client-product.yml config-server-client-test.yml 複製程式碼
配置檔案裡面都只有一行。
開發環境
environment: dev
複製程式碼
測試環境
environment: test
複製程式碼
線上環境
environment: product
複製程式碼
一般來說,config-server-client代表你專案的檔案,裡面三個檔案是這個專案開發、測試、線上的三個配置檔案! 4. 將配置檔案提交到github上。。倉庫就已經搭建好了,效果見下圖!
配置中心伺服器端搭建
搭建之前,先介紹一下我使用的springcloud版本。這裡我是使用最新的版本。。你們可以把下面程式碼放到自己專案的父pom依賴中
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
</parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Finchley.RC1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
複製程式碼
-
新建一個maven工程,取名springcloud-config-server
-
修改pom檔案,加入如下依賴
<!--配置中心--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency> 複製程式碼
-
新建配置檔案application.yml如下
server: port: 8083 spring: application: name: config-server cloud: config: server: git: uri: https://github.com/kingrocy/springcloud-config-server-repo.git searchPaths: '{application}' #application代表客戶端的名稱 這種寫法的目的是根據專案名稱將配置檔案區分開 username: password: label: master 複製程式碼
-
編寫啟動類
package com.yunhui; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.config.server.EnableConfigServer; /** * @Author: Yun * @Description: * @Date: Created in 2018-05-24 17:54 */ @SpringBootApplication @EnableConfigServer public class ConfigServerApplication { public static void main(String[] args) { SpringApplication.run(ConfigServerApplication.class); } } 複製程式碼
到此,我們的配置中心伺服器端已經搭建完成了!我們啟動應用,在瀏覽器下輸入如下地址進行測試:http://localhost:8083/config-server-client/dev
如果瀏覽器返回下面json 則代表伺服器端搭建完成!
{
"name": "config-server-client",
"profiles": [
"product"
],
"label": null,
"version": "9f48ac3dfd2d4bf14d3bef631188fe22dad57a45",
"state": null,
"propertySources": [
{
"name": "https://github.com/kingrocy/springcloud-config-server-repo.git/config-server-client/config-server-client-product.yml",
"source": {
"environment": "product"
}
}
]
}
複製程式碼
通過配置中心伺服器端訪問配置檔案有如下幾種形式
/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties
複製程式碼
其中application為專案名稱 profile為環境名稱 label為github 分支名稱(預設為master)
踩坑一:通過輸入http://localhost:8083/config-server-client/dev在瀏覽器端返回不了json。。一直返回xml,而且配置中心客戶端獲取配置檔案時,一直獲取不到!
解決辦法:上面的問題是因為在配置中心的pom檔案中匯入了一些多餘的springcloud的依賴包影響,,將多餘的依賴包都移除,重新啟動專案,一切正常!
配置中心客戶端搭建
-
建立專案springcloud-config-server-client
-
修改pom檔案如下:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>springcloud</artifactId> <groupId>com.yunhui</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>springcloud-config-server-client</artifactId> <dependencies> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency> <!-- eureka client需要 若沒有,eureka client無法啟動(啟動後會自動停止)踩坑二 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies> </project> 複製程式碼
-
在resource目錄下建立bootstrap.yml檔案
server: port: 8084 spring: application: name: config-server-client cloud: config: profile: dev label: master uri: http://localhost:8083 #springboop 2.0之後 spring-boot-starter-actuator將/refresh等介面關閉了。。通過下面配置開啟 踩坑三 management: endpoints: web: exposure: include: "*" 複製程式碼
注意:此處的配置檔案是叫bootstrap,而不是application。。因為bootstrap配置檔案時優先於applictaion載入的。。所以我們在bootsrap中配置配置中心的地址,讓專案在啟動的時候去拉此專案在配置中心的配置檔案,再進行載入!
-
建立啟動類。。
package com.yunhui; 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; /** * @Author: Yun * @Description: * @Date: Created in 2018-05-24 18:26 */ @SpringBootApplication @RestController @RefreshScope public class ConfigServerClientApplication { public static void main(String[] args){ SpringApplication.run(ConfigServerClientApplication.class); } @Value("${environment}") String environment; @RequestMapping("/env") public String from() { return environment; } } 複製程式碼
啟動專案,在瀏覽器中輸入http://localhost:8084/env。若瀏覽器中顯示dev,則客戶端配置拉取成功!若沒有,則檢查配置!
單機下熱部署
在之前的步驟中,我們搭建的配置中心服務端以及客戶端都已經成功了,客戶端已經可以拉取配置中心的配置檔案了。但是如果我們改了配置中心的配置檔案,,此時我們的客戶端是拉取不到最新的配置檔案的。。如果想要最新的配置檔案生效,還是得將專案重啟,此時,我們使用config-server提供的動態重新整理配置功能。。
步驟:
-
客戶端pom檔案新增依賴
<!--config-client需要 若沒有 則無法重新整理配置--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> 複製程式碼
-
在需要重新整理的配置上,再其類上加 @RefreshScope註解。。再使用post請求 請求
{客戶端IP}:{客戶端埠}/actuator/refresh
這個url,這樣客戶端就會重新整理在@RefreshScope下所有使用@Value引用的配置屬性了。
通過上面兩個步驟,我們實現了單機情況下的客戶端獲取最新配置檔案的方法.但這個方法是基於我們的客戶端很少,沒有幾個的情況下,我們可以用這種人工的方式。但是在我們的客戶端是一個大的叢集,裡面的機器有幾十甚至上百,那採取這種方式就是不可行的。所以我們需要採用下面的這種方式來叢集推送配置資訊
叢集下熱部署
原理:
叢集下的訊息推送是依賴於訊息佇列,配置中心能夠主動進行資訊推送,將最新的配置資訊通過訊息佇列分發到叢集的機器中,叢集中的機器自動讀取,重新載入
複製程式碼
步驟:(注意:以下步驟需要在配置中心伺服器和客戶端都需要進行操作的)
-
pom檔案中新增springcloud的封裝的訊息元件
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency> 複製程式碼
-
spring-cloud-starter-bus-amqp預設是整合rabbitmq,我們只需在配置檔案中加入rabbitmq的相關配置資訊即可使用
spring: rabbitmq: host: 192.168.0.16 port: 5672 username: 使用者名稱 password: 密碼 複製程式碼
通過上面的配置,配置中心伺服器和客戶端就會在啟動的時候自動連上rabbitmq。springcloud提供了一個api給訊息叢集。通過post請求呼叫叢集中的任意一臺機器(包括配置中心伺服器和客戶端)的下面這個url {ip}:{port}/actuator/bus-refresh
就可以使叢集中機器自動重新整理配置,實現熱部署!
引申
上面的配置修改後,需要人工去請求單機或叢集的介面來實現熱部署。這是比較浪費資源的。我們可以通過git的webhook的來實現自動化構建操作。這樣的話,在我們推送程式碼到線上分支時,git會自動監控檔案,如果檔案發生了變化,就可以呼叫我們的/actuator/bus-refresh
實現叢集熱部署了。
至此,springcloud的分散式配置中心已經搭建完成!