Spring Cloud Config配置中心的使用


Spring Boot項目代碼開發過程中有這樣一個原則:“約定大於配置”,SpringBoot為我們提供了properties和yml類型的文件供我們編寫配置文件,而這些配置文件的編寫是要遵循約定,這樣一來,就有了一個統一的規范,使得我們在使用任何第三方組件時,都能按照規則配置文件,減少耦合。

因此,我們在微服務開發時,會接觸到大量的配置,其中有的配置是基礎配置,也就是項目要跑起來所需的配置,或者第三方組件要用到的默認配置;同時也有些配置是我們業務需要的,是我們程序員自己定義的。基礎配置一般在項目運行之后不會輕易修改,但是自定義配置可能會因為業務的需要而進行修改,例如:一個打折促銷業務,在配置文件中配置了一個【折扣】屬性,需要在某個節日提高折扣力度,更改折扣數值。基於項目在運行過程中不能輕易重啟這個前提下,想要修改配置則是一個難題。然而Spring Cloud Config幫我們解決了這個問題,它可以實現配置文件的熱更新。

Spring Cloud Config原理

各個微服務不用在自己的項目代碼中維護配置文件,而是將配置文件統一存儲到第三方,一般是用git存儲,但也可以是svn、本地文件等。配置中心服務(服務端,Spring Cloud Config所定義的一個拉取配置文件的服務)會從這些地方拉取最新的配置,而其他微服務(客戶端)只需從配置中心服務拉取最新配置即可

Spring Cloud Config入門

最簡單的配置中心,就是僅僅啟動一個服務作為配置中心服務端。這里我選擇git來存儲配置文件

首先需要在git上創建一個倉庫,保存各種配置文件,如圖:
在這里插入圖片描述

其中config-client-dev.yml的內容如下:

user:
  username: config-dev
  password: 0

這里的配置文件名稱是有規律的,去掉后綴"-dev"前面的內容是配置中心客戶端的服務名

創建配置中心服務端

1.新建項目,引入依賴

新建一個Spring Boot微服務config-center,這個微服務需要被Spring cloud管理,需根據需要設定版本,希望讀者對Spring Cloud的使用已經有了基本的了解。引入依賴:

<!-- spring cloud config 服務端包 -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-config-server</artifactId>
</dependency>

2.編寫配置文件

這里與之前創建微服務不同,我們需要創建一個bootstrap.yml文件,bootstrap.yml在Spring Boot 啟動時會優先於application.yml被執行,它在程序引導時執行,應用於更加早期配置信息讀取。內容如下:

spring:
  application:
    name: config-center
  cloud:
    config:
      server:
        git:
          uri: https://github.com/ithushuai/config-center-demo #配置文件所在倉庫
          username: git用戶名
          password: git密碼
          default-label: master #配置文件分支
          search-paths: config  #配置文件所在根目錄
          timeout: 10 # 超時時間,單位s,可以設置長一點,國內訪問github比較慢,極容易出現訪問超時

再創建application.yml文件,內容如下:

server:
  port: 8084

3.編寫啟動類,加上@EnableConfigServer注解

@SpringBootApplication
@EnableConfigServer
public class ConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }
}

4.啟動服務,訪問git倉庫中的配置文件。有如下一些訪問規則:

/{application}/{profile}[/{label}]
/{application}-{profile}.yml
/{label}/{application}-{profile}.yml
/{application}-{profile}.properties
/{label}/{application}-{profile}.properties

application:服務名

profile:配置環境(dev、prod、test...)

label:git分支,默認master

例如想要訪問config-single-client-dev.yml,就可以按規則訪問如下接口:

http://localhost:8084/config-client-dev.yml

在瀏覽器中訪問該接口,能夠獲取配置文件內容,就說明配置中心服務端已經搭建好了
在這里插入圖片描述

創建配置中心客戶端

上述步驟走完,說明配置中心服務端已經搭建好,並且可用,現在需要搭建一個客戶端服務來測試能否從服務端拉取配置

1.創建項目,引入依賴

<!-- spring cloud config 客戶端包 -->
<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>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

2.編寫配置文件

bootstrap.yml:

# 必須使用bootstrap.yml定義這些配置,cloud config會默認加載這個配置文件中的配置
spring:
  profiles:
    active: dev
---
spring:
  profiles: dev
  application:
    name: config-client
  cloud:
    config:
      uri: http://localhost:8084
      label: master
      profile: dev
---
spring:
  profiles: prod
  application:
    name: config-client
  cloud:
    config:
      uri: http://localhost:8084
      label: master
      profile: prod

application.yml:

server:
  port: 8085

3.編寫啟動類,常規Spring Boot項目啟動類

@SpringBootApplication
public class ConfigClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigClientApplication.class, args);
    }
}

4.編寫一個Controller類,並注入自定義配置,來測試能否獲取配置文件屬性

@RestController
public class GitController {
    @Value("${user.password}")
    private String password;

    @RequestMapping("/show")
    public String getGitConfig(){
        return password;
    }
}

5.啟動項目,在瀏覽器中訪問http://localhost:8085/show,頁面顯示“0”,則表明可以正常獲取配置屬性
在這里插入圖片描述

自動刷新配置

如果我們修改git倉庫中配置文件的內容,比如將password改為1,此時瀏覽器訪問:http://localhost:8084/config-client-dev.yml

會發現結果更新為“1”,然而我們再訪問:http://localhost:8086/show,結果仍然為“0”。也就是說當git倉庫中的配置文件被修改后,配置中心客戶端並不能察覺出變化,這並沒有達到我們的初衷。要實現客戶端刷新配置文件,則需要actuator的支持,前面客戶端引入的spring-boot-starter-actuator就是為了使用actuator。做法如下:

1.在注入配置文件屬性的類上加上@RefreshScope注解

Controller類中注入了配置文件,因此在GitController類上加上@RefreshScope注解

@RestController
@RefreshScope //開啟刷新功能,在使用到配置的類上加。不使用bus時,使用當前服務地址,單獨訪問http://localhost:8085/actuator/refresh,即可實現本服務配置刷新
public class GitController {
    @Value("${user.password}")
    private String password;

    @RequestMapping("/show")
    public String getGitConfig(){
        return password;
    }
}

2.在application.yml中引入management配置文件,暴露actuator的接口

server:
  port: 8085
management:
  endpoints:
    web:
      exposure:
        include: "*"

加了以上配置,我們就可以使用actuator給我們提供的一些接口,例如/actuator/refresh

我們用postman測試http://localhost:8085/actuator/refresh接口,使用POST請求:
在這里插入圖片描述

如圖,一旦配置文件發生變化,接口返回值中就會有相應的提示,上述內容表明config-client的版本有更新,發生變化的屬性是user.password

此時瀏覽器再訪問http://localhost:8086/show,結果已經更新為1
在這里插入圖片描述

上述自動刷新的弊端

實際生產環境中,會有很多個微服務,假如涉及到多個服務的配置修改,又或者某個服務部署了在了多個服務器上進行負載均衡,這時就需要手動為刷新每個服務,因為只刷新某一個服務,其他服務是不會實現自動刷新的。

配合Spring Cloud Bus實現自動刷新所有服務

Spring Cloud Bus的核心原理就是利用消息隊列做廣播,可以支持RabbitMQ以及Kafka。這里使用RabbitMQ做消息中間件,前提需要安裝好RabbitMQ。

1.在配置中心服務端增加bus依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>

2.在application.yml中加入rabbitmq的配置

spring:
  rabbitmq:
    host: 192.168.18.130
    username: admin
    password: admin

3.在客戶端服務中同樣增加bus依賴和rabbitmq的配置

4.啟動兩個客戶端服務,分別設置啟動端口為8085,8086

可以在IDEA工具中設置啟動參數,步驟如下:

1)在右上角點擊Edit Configurations
在這里插入圖片描述

2)設置VM options:
在這里插入圖片描述

3)當前頁面左上角點擊復制按鈕,復制一個啟動參數,並設置端口為8086
在這里插入圖片描述
5.啟動兩個客戶端服務,在瀏覽器中分別訪問 http://localhost:8085/show,http://localhost:8086/show,顯示的結果與github上一致。此時,修改config-client-dev.yml中password的值為2,postman訪問配置中心服務的bus-refresh接口,注意這里是bus-refresh:http://localhost:8084/actuator/bus-refresh,請求方式為POST,請求成功postman不顯示任何內容

6.再次訪問兩個客戶端的接口,發現數據都做了刷新

在Eureka的管理下使用Spring Cloud Config

Spring cloud Config + Spring Cloud Bus已經可以實現配置文件的集中化管理,並且能夠實現配置文件自動刷新。但是基於Spring Cloud的分布式服務往往是由Eureka來對各個微服務進行管理,那么如何將Spring Cloud Config集成到Eureka注冊中心中去呢?以下步驟建立在Eureka注冊中心已經搭建好的基礎上

1.在配置中心服務中增加Euraka客戶端的依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>

2.在啟動類上加上@EnableDiscoveryClient注解

@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConfigApplication.class, args);
    }
}

3.配置文件中添加Eureka的配置

eureka:
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka

4.客戶端服務中增加Eureka客戶端依賴,啟動類上加上@EnableDiscoveryClient注解,在bootstrap.yml中加上Eureka配置,並修改config的配置,如下

eureka: # 這里eureka配置必須放在bootstrap.yml中,因為在項目啟動時,就需要注冊到注冊中心,然后去配置中心拉取配置,有先后順序
  client:
    service-url:
      defaultZone: http://127.0.0.1:10086/eureka
spring:
  profiles:
    active: dev
---
spring:
  profiles: dev
  application:
    name: config-client
  cloud:
    config:
      label: master
      profile: dev
      discovery: # 當config server注冊到eureka時配置
        enabled: true
        service-id: config-center # config server 在注冊中心的注冊名
---
spring:
  profiles: prod
  application:
    name: config-client
  cloud:
    config:
#      uri: http://localhost:8084 # 當不使用eureka注冊中心時,用uri配置config server的地址,當config server注冊到eureka時,無需該配置
      label: master
      profile: prod
      discovery: # 當config server注冊到eureka時配置
        enabled: true # 開啟從注冊中心查找服務功能
        service-id: config-center # config server 在注冊中心的注冊名

至此,在Spring Cloud中使用Config配置中心,以及配合bus實現自動刷新已經全部完成。如需參考完整代碼,可以訪問https://github.com/ithushuai/cloud

1.git倉庫中的配置文件的名稱要與客戶端服務的application name對應

2.bootstrap.yml先於application.yml加載,因此拉取配置文件功能相關的配置要在bootstrap.yml中配置,例如config的設置,Eureka的相關配置,application name的配置等等


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM