一、分佈式配置中心
在單機情況下,只有一個用戶來使用配置文件和服務,當多機情況下,用戶通過負載均衡來訪問配置文件和服務。然而,如果使用分佈式集羣來部署配置文件,我們把所有配置文件統一管理,當修改的時候直接通過配置中心進行修改即可。
對於傳統的單體應該用,嘗試用配置環境管理所有配置,例如一個SpringBoot應用,會把配置信息放在application.yml中。如果要切換環境,可設置多個profile,並在啓動的時候指定激活哪個配置文件,然而在微服務架構中,有以下的需求:
- 集中管理配置:一個使用微服務架構的應用系統可能會包括成千上萬個微服務,因此集中管理十分必要
- 不同環境不同配置:數據源在不同環境 (開發、測試、預發佈、生產)中是不同的
- 運行期間可動態調整:可根據每個微服務的負載情況,動態調整數據源連接池大小或熔斷閾值,並且在調整時不重啓微服務
- 配置修改後自動更新:如果配置內容發生變化,微服務能夠自動更新配置
因此,一個配置管理系統是很重要的,現在常見的做法是使用配置服務器管理配置。
SpringCloud Config用來爲分佈式系統中的微服務提供集中化配置的支持。它分爲服務端和客戶端,兩部分獨立使用,通過HTTP進行通信。服務端作爲配置倉庫和客戶端的中介。客戶端作爲分佈式系統中各個微服務應用。
Config-Server通過遠程和本地的git來對配置文件進行維護,其他的服務通過Config Server來獲取配置文件。
二、本地使用配置中心
首先我們搭建配置中心,新建一個SpringBoot應用,並添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
然後我們在啓動類Application中添加註解@EnableConfigServer,然後我們在resources文件夾下新建一個配置文件bootstrap.yml。
server:
port: 8888
spring:
application:
name: config-server
cloud:
config:
server:
native:
search-locations: classpath:config/
profiles:
active: native
之後我們在resources文件夾下新建config文件夾,並新建配置文件dev.yml,內容自定義。例如我們在其中輸入text: hello
。啓動應用後,在瀏覽器中輸入http://localhost:8888/dev.yml,即可訪問到配置文件。
服務端作爲配置倉庫,需要客戶端去調用,下面我們實現一個客戶端。首先添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
然後依舊在resources文件夾下創建bootstrap.yml文件
server:
port: 8889
spring:
application:
name: test
cloud:
config:
uri: http://localhost:8888
profile: dev
之後建立一個Controller類進行測試
@RestController
public class TestController{
@Value("${text}")
String text;
@RequestMapping("/hi")
public String getText(){
return "Message: " + text;
}
}
三、搭建遠程配置中心
遠程中心是通過Git將配置文件託管在代碼平臺上,我們修改server和client的配置文件即可,server的配置文件要修改爲
server:
port: 8888
spring:
application:
name: config-server
cloud:
config:
server:
git:
# 根據實際情況填寫
# 代碼倉庫的URI
uri: https://xxxxxxx.git
# 文件名或文件夾名
search-paths: xxxxx
# 用戶名
username: xxxx
# 密碼
password: xxxx
我們可以看到,在文件中我們直接明寫了用戶名和密碼,會對賬號安全造成極大的影響,我們可以對配置進行加密和解密。配置過程如下
- 服務器的加密和解密依賴Java Cryptography Extension, JCE
- 進行JCE的下載安裝,替換Java根目錄下的jre/lib/security下的local_policy.jar和US_export_policy.jar
- 完成了JCE的安裝後,可以嘗試啓動配置中心,SpringCloud會暴露幾個端點:
- /encrypt/status:加密功能狀態的節點
- /key:查看密鑰的端點
- /encrypt:對請求的body內容進行加密的端點
- /decrypt:對請求的body內容進行解密的端點
- 在config-server配置文件中加入
encrypt:
# 自己定義密鑰
key: xxx
- 在敏感信息的值加密後加上前綴{cipher}
四、高可用配置中心
如果我們要實現配置中心的高可用性,就要把其做成微服務,然後在Eureka Server上進行註冊,這樣就可以將其集羣化,實現高可用。首先我們要搭建一個Eureka Server的工程,在這篇文章中已經提過了。唯一不同的是我們不在application.yml中填寫配置信息了,可以將該文件刪除,新建bootstrap.yml。Eureka部分的代碼還是和以前一樣
server:
port: 8761
eureka:
instance:
hostname: localhost
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
spring:
application:
name: eureka-server
現在要做的就是把config-server和config-client都改造成Eureka Client,因此,在兩者的配置文件中都加入
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eurkea/
再繼續修改config-client的配置文件
server:
port: 8889
spring:
application:
name: test
cloud:
config:
profile: dev
label: master
discovery:
enabled: true
serviceId: config-server
最後,在兩個啓動類中添加@EnableEurekaClient註解
五、配置動態刷新
首先我們要在config-client的控制層的Controller類上添加@RefreshScope註解,並且添加依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
之後修改config-client的配置信息,添加以下內容
management:
endpoints:
web:
exposure:
include: refresh
之後在瀏覽器中輸入http://localhost:8889/actuator/refresh,即可進行更新
然而,這樣更新的方式要求我們對每一個客戶端應用都添加額外的代碼,且每次更新都需要調用上面的URL,因此我們可以應用SpringCloud Bus使用自動刷新。SpringCloud Bus是一條消息總線,每個客戶端接收到配置更新的消息,都會主動向Config server請求更新配置文件。我們需要通過消息代理中間件RabbitMQ和Git的Webhooks來觸發更新。
那麼下面我們來實現這個組件,首先依舊要保留config-client中的@RefreshScope註解,並且加入依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
之後繼續修改config-client的配置信息
management:
endpoints:
web:
exposure:
include: bus-refresh
server:
port: 8889
spring:
application:
name: test
cloud:
config:
profile: dev
label: master
discovery:
enabled: true
serviceId: config-server
fail-fast: true
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
啓動RabbitMQ服務後,訪問localhost:15672/#/即可來到主頁,消息的發送和接收可以在Queues中找到。
歡迎加入交流羣QQ1107710098