SpringCloud實戰7-Config分佈式配置管理

SpringCloud實戰7-Config分佈式配置管理

分佈式環境下的統一配置框架,已經有很多了,好比百度的disconf,阿里的diamandhtml

官方文檔對spring Cloud Config的描述以下:

  Spring Cloud Config爲分佈式系統中的外部配置提供服務器和客戶端支持,使用Config Server,您能夠在全部環境中管理應用程序的外部屬性。客戶端和服務器上的概念映射與Spring Environment和PropertySource抽象相同,mysql

  所以它們與Spring應用程序很是契合,但能夠與任何以任何語言運行的應用程序一塊兒使用。隨着應用程序經過從開發人員到測試和生產的部署流程,您能夠管理這些環境之間的配置,並肯定應用程序具備遷移時須要運行的一切。git

  服務器存儲後端的默認實現使用git,所以它輕鬆支持標籤版本的配置環境,以及能夠訪問用於管理內容的各類工具。很容易添加替代實現,並使用Spring配置將其插入。web

 

1.爲何要配置中心?

一個應用中不僅是代碼,還須要鏈接資源和其它應用,常常有不少須要外部設置的項去調整應用行爲,如切換不一樣的數據庫,設置功能開關等。spring

隨着系統微服務的不斷增長,首要考慮的是系統的可伸縮、可擴展性好,隨之就是一個配置管理的問題。各自管各自的開發時沒什麼問題,到了線上以後管理就會很頭疼,到了要大規模更新就更煩了。sql

並且你不可能中止你的服務集羣去更新的你配置,這是不現實的作法,所以springcloud配置中心就是一個比較好的解決方案,下圖就是一個springcloud配置中心的解決方案:數據庫

 

常見的配置中心的實現方法有:json

  1.硬編碼(缺點:須要修改代碼,風險大)bootstrap

  2.放在xml等配置文件中,和應用一塊兒打包(缺點:須要從新打包和重啓)後端

  3.文件系統中(缺點:依賴操做系統等)

  4.環境變量(缺點:有大量的配置須要人工設置到環境變量中,不便於管理,且依賴平臺) 5.雲端存儲(缺點:與其餘應用耦合)

 

Spring Cloud Config就是雲端存儲配置信息的,它具備中心化,版本控制,支持動態更新,平臺獨立,語言獨立等特性。其特色是:

  1.提供服務端和客戶端支持(spring cloud config server和spring cloud config client)   2.集中式管理分佈式環境下的應用配置   3.基於Spring環境,無縫與Spring應用集成   4.可用於任何語言開發的程序   5.默認實現基於git倉庫,能夠進行版本管理   6.可替換自定義實現
 

spring cloud config包括兩部分:

  1.spring cloud config server 做爲配置中心的服務端:

    1.拉取配置時更新git倉庫副本,保證是最新結果

    2.支持數據結構豐富,yml, json, properties 等

    3.配合 eureke 可實現服務發現,配合 cloud bus 可實現配置推送更新

    4.配置存儲基於 git 倉庫,可進行版本管理

    5.簡單可靠,有豐富的配套方案

  2.Spring Cloud Config Client 客戶端:

    1.Spring Boot項目不須要改動任何代碼,加入一個啓動配置文件指明使用ConfigServer上哪一個配置文件便可

 

SpringCloud Config與百度的disconf之類的有很大不一樣,主要區別在於下面三點:

  1.配置的存儲方式不一樣:disconf是把配置信息保存在mysql、zookeeper中,而spring cloud config是將配置保存在git/svn上 (即:配置當成源代碼同樣管理)

  2.配置的管理方式不一樣:spring cloud config沒有相似disconf的統一管理界面,既然把配置都當成git之類的源碼來看待了,git的管理界面,就是配置的管理界面

  3.配置變化的通知機制不一樣:disconf中配置變化後,依賴zk的事件watcher來通知應用,而spring cloud config則是依賴git每次push後,觸發webhook回調,最終觸發spring cloud bus(消息總線),而後由消息總線通知相關的應用。

從配置變化的通知機制上看,若是有100個應用節點,都依賴於統一配置,若是修改了配置,只想讓某幾個節點"灰度"更新配置,spring cloud config server更容易作到,這一點相對disconf更靈活

 

首先SpringCloud Config 是分爲Server端和Client端的,Server端負責管理配置,Client端用來加載配置。咱們每個爲服務都要集成一個Client端的。上面也提到過。所以,咱們如今看一下Config的Server端的Demo實現。

首先在原來的項目中新建一個springcloud-config-server模塊,而且引入相關依賴,以下:

複製代碼
  <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-config-server</artifactId>
        <version>1.4.0.RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-eureka</artifactId>
        <version>1.3.5.RELEASE</version>
    </dependency>
複製代碼

咱們能夠看到引入了Eureka,爲何呢?很明顯是爲了高可用。

接着在啓動類上面加入@EnableConfigServer註解,表示這裏是配置中心服務。還有Eureka的客戶端的註解代碼以下:

複製代碼
@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }
}
複製代碼

application.yml配置以下:

複製代碼
server:
  port: 7000
#服務名字
spring:
  application:
    name: config-server
  cloud:
    config:
      server:
        git:
#git 倉庫的地址
          uri: https://gitee.com/xxxx/springcloud-config.git
#git 倉庫的帳號密碼
          username: xxx
          password: xxx
#加入註冊中心,實現高可用
eureka:
  client:
    service-url:
       defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/
複製代碼

注意了,前提是你必需要在git倉庫中先創建一個倉庫,而後配置兩個配置,一個開發dev,一個測試test  以下圖:

dev的內容以下:

test的內容以下:

好了,讓咱們把springcloud-config模塊啓動起來,啓動啓動類,運行,訪問git倉庫中的cloud-config-dev.properties,以下:

 

接下來,咱們進行springcloud Config的Client端的Demo,以下:

首先引入Client端的相關依賴,以下:

複製代碼
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-config</artifactId>
            <version>1.4.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-eureka</artifactId>
            <version>1.3.5.RELEASE</version>
        </dependency>
複製代碼

這裏提一下,爲何須要引入前面的actuctor依賴,由於,咱們Client端須要在不重啓的狀況下,及時更新拉取加載配置中心的改變,而後修改內存中的配置的值。 

接着在Client啓動類的打上@EnableDiscoveryClient的註解,來註冊到註冊中心去,以下:

複製代碼
@SpringBootApplication
@EnableDiscoveryClient
public class ConfigClientApplication {

    public static void main(String[] args) {
        SpringApplication.run(ConfigClientApplication.class, args);
    }
}
複製代碼

 

接下來這步驟很關鍵,就是要將Client模塊下的application.yml文件改成bootstrap.yml,這是很關鍵的,由於bootstrap.yml是比application.yml先加載的。bootstrap.yml優先級高於application.yml。就比如如,你應用程序都跑起來了,你配置還沒加載,這不是扯淡嗎?

以下:

 

 

 

複製代碼
server:
  port: 7005
spring:
  application:
    name: cloud-config
  cloud:
    config:
#啓動什麼環境下的配置,dev 表示開發環境,這跟你倉庫的文件的後綴有關,好比,倉庫配置文件命名格式是cloud-config-dev.properties,因此profile 就要寫dev
      profile: dev
#面向服務,容許被發現 discovery: enabled: true #這個名字是Config Server端的服務名字,不能瞎寫。 service-id: config-server #註冊中心 eureka: client: service-url: defaultZone: http://localhost:8888/eureka/,http://localhost:8889/eureka/ #是否須要權限拉去,默認是true,若是不false就不容許你去拉取配置中心Server更新的內容 management: security: enabled: false
複製代碼

 

 接着寫一段測試代碼,以下,創建一個測試Controller,代碼以下:

複製代碼
@RestController
//這裏面的屬性有可能會更新的,git中的配置中心變化的話就要刷新,沒有這個註解內,配置就不能及時更新
@RefreshScope
public class TestController {

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

    @RequestMapping("/test")
    public String test(){
        return this.name+this.age;
    }
}
複製代碼

接着啓動啓動該工程,運行結果以下:

首先咱們咱們先看沒更新配置以前的值,以下:

接着咱們去git倉庫中修改age的值爲24,再用postman來發送post請求localhost:7005/refresh,以下:

能夠看到postman返回config.client.version信息,表示告知Client,遠程的倉庫中的配置中心已經更新了的配置版本信息,改變的值爲age。

接着咱們繼續刷新瀏覽器,localhost:7005/test,看一下年齡是否更新了,以下:

能夠看到年齡跟新到24了。

 

可是這樣就行了嗎?雖然服務沒有重啓,可是咱們要一個服務一個服務的發送post請求,咱們能受的了嗎?這比以前的沒配置中心好多了,那麼咱們如何繼續避免挨個挨個的向服務發送Post請求來告知服務,你的配置信息改變了,須要及時修改內存中的配置信息。

這時候咱們就不要忘記消息隊列的發佈訂閱模型。讓全部爲服務來訂閱這個事件,當這個事件發生改變了,就能夠通知全部微服務去更新它們的內存中的配置信息。這時Bus消息總線就能解決,這留到下一篇隨筆講解。

相關文章
相關標籤/搜索