分散式配置中心spingcloud-config-server

天晴朗好風光發表於2018-11-28

原文地址:

http://118.25.172.253/2018/11/16/分散式配置中心spingcloud-config-server搭建/

分散式配置中心spingcloud-config-server

分散式配置中心我的專案早就在使用了,是我一個同事搭建的,對於這個,我只是瞭解一點。所以抽空自己搭建了一個,其中也發現了不少問題。所以寫了這篇文章記錄一下搭建過程!相信跟著我寫的步驟,,大部分人應該可以搭建成功的!通過這篇文章後,你也可以學會單機、叢集下實現應用的熱部署

簡介

Spring Cloud Config為分散式系統中的外部化配置提供伺服器和客戶端支援。使用Config Server,您可以在所有環境中管理應用程式的外部屬性。客戶端和伺服器對映的概念與Spring Environment和PropertySource抽象相同,因此它們與Spring應用程式非常契合,但可以與任何以任何語言執行的應用程式一起使用。隨著應用程式通過從開發人員到測試和生產的部署流程,您可以管理這些環境之間的配置,並確定應用程式具有遷移時需要執行的一切。伺服器儲存後端的預設實現使用git,因此它輕鬆支援標籤版本的配置環境,以及可以訪問用於管理內容的各種工具。可以輕鬆新增替代實現,並使用Spring配置將其插入。

以上簡介來自springcloud的中文文件

配置中心倉庫搭建

這裡我們使用github作為我們的配置檔案倉庫。

  1. 現在github上建立一個倉庫,我的倉庫名叫springcloud-config-server-repo

  2. 將倉庫克隆到本地

  3. 在倉庫下新建一個目錄,叫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上。。倉庫就已經搭建好了,效果見下圖!

image

配置中心伺服器端搭建

搭建之前,先介紹一下我使用的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>
複製程式碼
  1. 新建一個maven工程,取名springcloud-config-server

  2. 修改pom檔案,加入如下依賴

     <!--配置中心-->
     <dependency>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-config-server</artifactId>
     </dependency>
    複製程式碼
  3. 新建配置檔案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
    複製程式碼
  4. 編寫啟動類

     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的依賴包影響,,將多餘的依賴包都移除,重新啟動專案,一切正常!

配置中心客戶端搭建

  1. 建立專案springcloud-config-server-client

  2. 修改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>
    複製程式碼
  3. 在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中配置配置中心的地址,讓專案在啟動的時候去拉此專案在配置中心的配置檔案,再進行載入!

  1. 建立啟動類。。

     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提供的動態重新整理配置功能。。

步驟:

  1. 客戶端pom檔案新增依賴

     <!--config-client需要 若沒有 則無法重新整理配置-->
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-actuator</artifactId>
     </dependency>
    複製程式碼
  2. 在需要重新整理的配置上,再其類上加 @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的分散式配置中心已經搭建完成!

專案原始碼:springcloud學習筆記

相關文章