前沿:參考文章,非常建議食用
上面的兩篇文章裏面都是config-server向eureka註冊,其它服務根據config-server在eureka中的名稱獲取微服務實例後再獲取對應自身的配置文件,這樣確實可以完成,但是有一個問題,因爲這樣config-server需要依賴eureka,即eureka必須先跑起來(即eureka的配置文件必須在本地),這樣一來如果eureka也想把配置文件放在github上,他們就會衝突,另一種方法是如果向我後面這樣(章節四)直接指定ip和端口,雖然可以解決問題,將eureka的配置文件也放在遠端,可是,這樣一來,eureka無法獲取config-server搭建的集羣,兩種方式如下(第一至三節爲第一種,第四節爲第二種)
一、說明
模塊說明:
模塊名稱 | 說明 |
---|---|
eureka | 服務的註冊中心 |
config-server | springCloud-config的服務中心 |
stock | 庫存模塊 |
user | 用戶模塊 |
步驟如下:
- 服務向eureka中心,報告自身的信息,如自身模塊在eureka中的服務名稱,以及IP和port
- config-server 模塊需要取對應存放配置文件的地方(如github,gitlab等)讀取配置,那麼就需要配置這些地方的賬號密碼,以及倉庫和對應的目錄
- stock模塊以及user模塊都需要config-server在eureka中的服務名稱,並設置需要的配置文件的名稱
- 需要明白在springBoot中bootstrap.properties比application.properties的文件優先級要高,會首先加載bootstrap.properties
2、建立demo測試
2.1、創建eureka模塊
直接建立一個eureka模塊即可,和以往的springcloud模塊建立一模一樣,
這裏eureka的配置文件採用本地的方式(關於把eureka的配置文件也放在git服務器上,請看文章第四節),這裏就不再囉嗦了
2.2、創建config-server模塊
2.2.1、依賴
因爲是springcloud-config的服務端,所以我們需要config的server依賴
<dependencies>
<!--Eureka客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--springCloud-config服務端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
</dependency>
</dependencies>
2.2.2、啓動類
需要開啓@EnableConfigServer
@SpringBootApplication
@EnableConfigServer
@EnableDiscoveryClient
public class ConfigServerApplication {
public static void main(String[] args) {
SpringApplication.run(ConfigServerApplication.class,args);
}
}
2.2.2、配置文件
配置文件如下
spring.application.name=config-server
server.port=9005
eureka.client.serviceUrl.defaultZone= http://localhost:8005/eureka/
eureka.instance.prefer-ip-address = true
spring.cloud.config.server.git.uri = https://github.com/wandun/config-repo
spring.cloud.config.server.git.search-paths = /userModuleConfig,/stockModuleConfig
spring.cloud.config.server.git.username = github的用戶名
spring.cloud.config.server.git.password = github的密碼
spring.cloud.config.server.git.skip-ssl-validation=true
說明:
- spring.application.name: 這個是指定該模塊在eureka中的服務名稱。
- server.port:服務指定的端口。
- eureka.client.serviceUrl.defaultZone: 這個是設置與Eureka Server交互的地址,客戶端的查詢服務和註冊服務都需要依賴這個地址。
- spring.cloud.config.server.git.uri: 配置的Git倉庫的地址,我這裏是專門建立了一個github的倉庫
- spring.cloud.config.server.git.search-paths: git倉庫地址下的相對地址 多個用逗號","分割。
- spring.cloud.config.server.git.username:git倉庫的賬號。
- spring.cloud.config.server.git.password:git倉庫的密碼。
對應上面的 search-paths = /userModuleConfig,/stockModuleConfig,一個目錄對應一個模塊的配置文件,每一個模塊又都有dev,uat,pro三種配置環境
每一個配置文件只有兩項
- tockconfig-dev (uat/pro).properties
server.port=8088 # (stock 模塊的啓動端口)
current.profile=dev # 根據當前的配置文件(uat ,dev, pro)
- userconfig-dev (uat/pro).properties
server.port=8089 # (user模塊的啓動端口)
current.profile=dev # 根據當前的配置文件(uat ,dev, pro)
2.3、創建stock模塊
2.3.1、依賴
後面因爲需要通過瀏覽器訪問,所以需要web依賴,而且因爲stock是springcloud-config的客戶端,所以我們需要config的client依賴,並且我們需要向eureka註冊,所以我們需要eureka的客戶端
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Eureka客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!-- 配置config客戶端 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
</dependencies>
2.3.2、啓動類
@SpringBootApplication
@EnableDiscoveryClient
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class,args);
}
}
2.3.2、配置文件
這個模塊的配置文件名稱一定一定要是bootstrap開頭,不能是application,因爲stock模塊的配置文件不是讀取本地的application.properties,而是需要去獲取遠端的,所以我們使用bootstrap的 優先級會更高,在加載application之前包配置從遠端讀取到手後就可以了!
spring.cloud.config.name=stockconfig
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
eureka.client.serviceUrl.defaultZone=http://localhost:8005/eureka/
eureka.instance.prefer-ip-address = true
說明:
- spring.cloud.config.name: 獲取配置文件的名稱的前綴,請詳細查看前面倉庫說明截圖
- spring.cloud.config.profile: 獲取配置的策略,dev,uat,pro
- spring.cloud.config.label:獲取配置文件的分支,默認是master。如果是- 是本地獲取的話,則無用。
-spring.cloud.config.discovery.enabled: 開啓配置信息發現。- spring.cloud.config.discovery.serviceId: 指定配置中心(config-server)在eureka中的service-id
- eureka.client.serviceUrl.defaultZone: 這個是設置與Eureka Server交互的地址,客戶端的查詢服務和註冊服務都需要依賴這個地址。
- eureka.instance.prefer-ip-address: 在eureka中顯示具體的ip
這裏stock模塊爲什麼可以找到config-server服務,是通過前面的配置
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
因爲config-server再eureka中進行了註冊
2.3.3、編寫測試接口
我這裏在對應的模塊寫了一個接口,獲取當前配置文件中的current.profile的值,因爲我們之前在每一個環境中的配置文件對應的值是不同的,所以只要我們切換環境,那麼配置會發生變化,current.profile值也就會發生變化
@RestController
public class StockController {
private static final String currentProjectName = "stock";
@Value("${current.profile}")
private String currentProfile;
/**
* 測試配置是否及時生效
* @return
*/
@GetMapping("/getCurrentProfile")
public String getCurrentProfile(){
return currentProjectName+":"+currentProfile==null?"null":currentProfile;
}
}
2.4、創建user模塊
這個模塊與stock模塊創建一致,只是配置文件不同,因爲兩個模塊的配置文件的地址也不同,如下
# 獲取配置文件的名稱
spring.cloud.config.name=userconfig
spring.cloud.config.profile=dev
spring.cloud.config.label=master
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
eureka.client.serviceUrl.defaultZone=http://localhost:8005/eureka/
eureka.instance.prefer-ip-address = true
2.5、測試
先請求一次我們呢之前配置的那個接口,更改配置後(需要重啓),再去請求一次,會發生變化
3、自動刷新配置
過程如下:
- 1、提交配置觸發post請求給server端的bus/refresh接口
- 2、server端接收到請求併發送給Spring Cloud Bus總線
- 3、Spring Cloud bus接到消息並通知給其它連接到總線的客戶端
- 4、其它客戶端接收到通知,請求Server端獲取最新配置
- 5、全部客戶端均獲取到最新的配置
以上通信使用的是amqp(其實現又rabbitmq),或者你可以使用kafka
3.1、改變config-server
3.1.1、pom.xml的修改
增加actuator依賴,和bus-amqp依賴
<!--
通過 bus通知配置的修改(實現是通過消息中間件 amqp),
再通過 actuator 的開放的端口,自動刷新配置(這樣只要一改變配置,我們的客戶端就會收到信息)
-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
3.1.2、application.properties的修改
需要開啓actuator 的bus-refresh端點,開啓bus的發現,通知功能,並配置通知消息的中間件的地址賬號以及密碼,即增加如下配置
# 開啓actuator 的bus-refresh端點
management.endpoints.web.exposure.include= bus-refresh
#spring.cloud.bus.enabled = true
#spring.cloud.bus.trace.enabled = true
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
3.2、改變客戶端
這裏我就只修改stock這一個客戶端,作爲列子,user客戶端就不再改了
3.2.1、pom.xml的修改
增加actuator依賴,和bus-amqp依賴
<!-- 監聽config-server在消息中間件中發出的配置,來跟新配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bus-amqp</artifactId>
</dependency>
3.2.2、bootstrap.properties的修改
需要開啓actuator 的bus-refresh端點,開啓bus的發現,通知功能,並配置通知消息的中間件的地址賬號以及密碼,即增加如下配置
# 開啓actuator 的bus-refresh端點
management.endpoints.web.exposure.include= bus-refresh
#spring.cloud.bus.enabled = true
#spring.cloud.bus.trace.enabled = true
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
3.2.3、增加註解
在使用到配置文件中的值的位置,增加註解 @RefreshScope,這個很重要,如果沒有這個註解,配置還是不會刷新,如下
但是如果修改的是spring中官方配置(如改變了jdbc的連接用戶沒和密碼等等),則不需要請求rereshe接口,但是如果是自定義的,那麼就需要請求rereshs接口
3.3、rabbitmq安裝
這個就省略了,大家自行百度,用win或者linux都可以
3.4、測試
- 1、依次啓動eurek,config-server,stock,請求我們自己寫的接口,獲取當前的current.profile的值
-
http://localhost:8088/getCurrentProfile
-
- 2、然後修改github倉庫中對應配置文件的current.profile的值
- 3、再使用postman發送post請求,請求config-server的服務9005,不用擔心actuator/bus-refresh這個接口沒有寫,actuator模塊已經做了,(actuator模塊中會有多個端口,用來檢測當前項目的健康情況,大家也可以去百度自行了解以下springcloud-actuator模塊)
http://localhost:9005/actuator/bus-refresh
- 4、請求完成,我們再請求我們自己的接口,就會發現,配置就是你修改完後的數值了
4、完善
前面本地文件中還是有eureka和config-server,現在我們也可以把eureka的配置文件上傳到git服務器上本地文件只有config-server,那麼其它服務就不能再通過eureka中的服務名稱來尋找config-server,而且config-server也不能向eureka註冊了,我們要做的就在配置文件bootstarp.properties中指定config-server的地址!
所以我們這裏在我們的github的倉庫中再增加一個eureka的目錄和3個環境的配置文件
最後將eureka項目的application.properties文件替換成bootstrap.properties即可,內容如下
# 獲取配置文件的名稱
spring.cloud.config.name=eureka
spring.cloud.config.profile=dev
spring.cloud.config.label=master
# 需要知道 config-server服務的地址
spring.cloud.config.uri=http://localhost:9005
# 開啓actuator 的bus-refresh端點(讀取配置的客戶端可以不開啓)
#management.endpoints.web.exposure.include=bus-refresh
#spring.cloud.bus.enabled = true
#spring.cloud.bus.trace.enabled = true
# 接收 config-server的bus發出的配置修改的信息,以及時獲取最新配置
spring.rabbitmq.host=127.0.0.1
spring.rabbitmq.port=5672
spring.rabbitmq.username=guest
spring.rabbitmq.password=guest
stock和user模塊的修改,即將前面配置中的
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
改爲
# 需要知道 config-server服務的地址,不能通過eureka中的服務名稱去找,
# 因爲eureka本身還需要先知道config-server的地址,會自相矛盾
spring.cloud.config.uri=http://localhost:9005
不再通過serviceId尋找,而是通過指定的ip+port找config-server
啓動順序
config-server -----> eureka -----> stock/user
5、後言
關於服務知道config-server的地址有兩種方式
- 第一種,通過config-server在eureka中註冊後其它服務根據serviceId來尋找,(但是需要將config-server註冊到eureka中)
spring.cloud.config.discovery.enabled=true
spring.cloud.config.discovery.serviceId=config-server
- 第二種,指定地址ip+port
# 需要知道 config-server服務的地址,不能通過eureka中的服務名稱去找,
# 因爲eureka本身還需要先知道config-server的地址,會自相矛盾
spring.cloud.config.uri=http://localhost:9005
其實第一中和第二種可以混合使用,但是如果想要eureka的配置文件不在本地,那麼在eureka的bootstrap.properties配置文件中就必須使用第二種方式,其它服務可以通過第一種,(但是前提是需要在config-server中指定eureka的地址),啓動順序不變,只是一開始config-server會拋出異常,是因爲找不到eureka,等我們把eureka跑起來後,就可以了,大約幾秒後eureka中就會有config-server這個服務,其它服務就可以根據serviceId來找config-server了,爲什麼其它服務不直接也使用第二種方式呢?其實可以使用,但是如果我們想給confih-server搭建集羣的話,就只能使用第一種方式了,但是即使這樣,還是存在一個問題,那就是eureka獲取不到config-server的集羣實例!
以上是我個人的一點總結,斯卡帕,如果文章有問題,還望各位看官海涵,可以在下方評論指出,謝謝!