一、實現原理
1、ConfigServer(配置中心服務端)從遠端git拉取配置文件并在本地git一份,ConfigClient(微服務)從ConfigServer端獲取自己對應 配置文件;
2、當遠端git倉庫配置文件發生改變,ConfigServer如何通知到ConfigClient端,即ConfigClient如何感知到配置發生更新?
Spring Cloud Bus會向外提供一個http接口,即圖中的/bus/refresh。我們將這個接口配置到遠程的git的webhook上,當git上的文件內容發生變動時,就會自動調用/bus-refresh接口。Bus就會通知config-server,config-server會發布更新消息到消息總線的消息隊列中,其他服務訂閱到該消息就會信息刷新,從而實現整個微服務進行自動刷新。
二:實現方式
實現方式一:某個微服務承擔配置刷新的職責
1、提交配置觸發post調用客戶端A的bus/refresh接口
2、客戶端A接收到請求從Server端更新配置并且發送給Spring Cloud Bus總線
3、Spring Cloud bus接到消息并通知給其它連接在總線上的客戶端,所有總線上的客戶端均能收到消息
4、其它客戶端接收到通知,請求Server端獲取最新配置
5、全部客戶端均獲取到最新的配置
存在問題:
1、打破了微服務的職責單一性。微服務本身是業務模塊,它本不應該承擔配置刷新的職責。2、破壞了微服務各節點的對等性。3、有一定的局限性。WebHook的配置隨著承擔刷新配置的微服務節點發生改變。
改進如下方式二:配置中心Server端承擔起配置刷新的職責,原理圖如下:
1、提交配置觸發post請求給server端的bus/refresh接口
2、server端接收到請求并發送給Spring Cloud Bus總線
3、Spring Cloud bus接到消息并通知給其它連接到總線的客戶端
4、其它客戶端接收到通知,請求Server端獲取最新配置
5、全部客戶端均獲取到最新的配置
三:實現步驟
基本步驟:1、添加依賴 2、修改配置文件 3、添加注解
備注:這里給出方式二配置方法,方式一的區別在:因為是某個微服務承擔配置刷新的職責,所以Server端不需要配置 Rabbitmq和添加bus-amqp的依賴。
<一>Config Server端配置(提前安裝rabbitmq移步鏈接:)
1、添加依賴
<!-- config-server依賴 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
<!-- springcloud-bus依賴實現配置自動更新,rabbitmq -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
2、修改配置文件Bootstrap.yml文件
server:
port: 9090
spring:
application:
name: config-server
cloud: #config服務端,從git拉取數據
config:
server:
git:
uri: https://github.com/****/config-repo # 配置git倉庫的地址
username: # git倉庫的賬號
password: # git倉庫的密碼
search-paths: /*/*/*,/* #倉庫下配置文件搜索路徑
rabbitmq: #本地環境不需要配置mq,但是需要啟動mq,Springboot會自動連接本地mq
host: localhost
port: 5672
username: guest
password: guest
eureka: #注冊服務
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
#defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ #eureka高可用
management: #SpringCloud 1.5版本暴露接口,暴露/bus-refresh接口
security:
enabled: false
# endpoints: #SpringCloud 2.0.0版本以后暴露接口方式
# web:
# exposure:
# include: "*"
security: #是否開啟基本的鑒權,默認為true
basic:
enabled: false
備注:關于git倉庫配置那塊,參考這篇博客:http://www.cnblogs.com/hellxz/p/9306507.html
本地環境不需要配置mq,但是需要啟動mq,Springboot會自動連接本地mq,后面客戶端也是,如果是線上環境的話,必須要進行配置,原因看看SpringCloud bus如下說明:
3、啟動類增加注解 @EnableConfigServer
至此Config-Server端已配置完畢
<二>Config Client端配置
1、添加依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
2、修改配置文件Bootstrap.yml文件
server:
port: 9092
spring:
application:
name: config-client #對應微服務配置文件名稱
cloud:
config:
uri: http://localhost:9090/ #config server 端地址
profile: dev #項目配置文件選擇
label: master #git倉庫的分支
discovery:
enabled: true
service-id: config-server #config-server服務名稱
rabbitmq: #本地環境不需要配置mq
host: localhost
port: 5672
username: guest
password: guest
security: #
basic:
enabled: false
3、添加注解: @RefreshScope添加在需要刷新的配置文件上
注明:自動刷新只能刷新 @RefreshScope 注解下的配置,一些特殊配置,如數據庫等,需要同樣先設置數據庫鏈接ConfigServer類,然后通過加 @RefreshScope 注解方式
到這里Config-Server端和Client端已經配置完畢,先后啟動Server端和Client端,post請求方式進行測試:http://localhost:9090/bus/refresh
<三>配置git的webhook
前面已準備就緒,啟動Server端和Client端,要實現配置自動刷新需要調用/bus-refresh接口通知config-Server
方式一:手動調用(post請求):http://localhost:9090/bus/refresh(Server端地址)
方式二:配置git的webhook ,當git端配置發生改變,自動調用/bus-refresh接口
<四>附件
config-client-dev.yml配置文件:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
url: jdbc:mysql://127.0.0.1:3306/test_mybatis_db?autoReconnect=true&useSSL=false&useUnicode=true&characterEncoding=UTF-8
username: root
password: 1234
driverClassName: com.mysql.jdbc.Driver
druid:
initialSize: 5
minIdle: 5
maxActive: 20
maxWait: 60000
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: SELECT 1
testWhileIdle: true
filters: stat,wall,log4j
mybatis:
type-aliases-package: com.scnu.springcloudconfigclient.domain
mapper-locations: classpath*:mapper/*.xml
eureka: #注冊服務
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
custom:
username: guest-new
passwd: guest-new
profile: test-new
<五>加解密
引入:配置文件統一放在配置中心,配置中心文件明文存在不安全,容易泄露比如數據庫用戶名、密碼等,如何實現git倉庫配置文件為密文時,通過配置中心在Config-Server端進行解密。
<一>對稱加密
1、JCE加密,Oracl官網下載,替換本機JDK下JRE的lib下在兩個文件。
https://www.oracle.com/technetwork/java/javase/downloads/jce-all-download-5170447.html
2、
a) Config-Server 端配置文件添加:
encrypt: #加密因子
key: foobar
加密因子為foobar,這里借助了Server端的加密,因此配置完畢需要啟動Config-Server
b) 啟動Config-Server
$ curl -X post http://localhost:9090/encrypt -d mysecret
加密mysecret為密碼,得到如下加密字串:
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
c) 逆向操作:
$ curl -X post http://localhost:9090/decrypt -d 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
解密得到:
mysecret
3、使用:
a) Config-Server端配置文件中加入:
encrypt: #加密因子foobar
key: foobar
b) Git倉庫中配置文件caiyun-test-dev.yml
profile: '{cipher}682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda'
備注:.properties文件吧引號去掉
c) Config-client不需要做任何操作
<二>非對稱加密
RSA算法
1、命令行下執行
$ keytool -genkeypair -alias mytestkey -keyalg RSA -dname "CN=Web Server,OU=Unit,O=Organization,L=City,S=State,C=US" -keypass changeme -keystore server.jks -storepass letmein
執行完生成 server.jks 文件,加密文件
2、將Server.jks 文件放在Config-Server的ClassPass路徑下,
Config-Server 端配置文件bootstrap.yml中添加:
encrypt:
keyStore:
location: classpath:/server.jks #生成在jks文件路徑
password: letmein #key store 秘鑰
alias: mytestkey #別名
secret: changeme #私鑰
啟動Config-Server
3、加密
$ curl -X post http://localhost:9090/encrypt -d caiyun-mima
加密caiyun-mima,得到如下加密字串:
682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
4、使用:
a)Config-Server端配置文件中加入:
encrypt:
keyStore:
location: classpath:/server.jks #生成在jks文件路徑
password: letmein #key store 秘鑰
alias: mytestkey #別名
secret: changeme #私鑰
b) Git倉庫中配置文件caiyun-test-dev.yml
profile: '{cipher}682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda'
備注:.properties文件吧引號去掉
c) Config-client不需要做任何操作