經過前面章節,咱們已經學習了 SpringCloud 的不少組件,每一個組件都建立了一個工程,而每一個工程都會有一個配置文件,而且有些配置是同樣的。例如:在實際項目中,咱們建立了用戶和訂單兩個服務,這兩個服務是同一個數據庫,那麼咱們在這兩個服務的配置文件都會配置相同的數據源,一旦咱們的數據庫地址發生改變(只是一種狀況),用戶和訂單兩個服務的配置文件都須要改,這仍是隻是兩個服務,在一個大型系統(好比淘寶),將會有成千上萬個服務,按照這種方式代價無疑是巨大的。java
不過無需擔憂,正所謂上有政策,下有對策,既然有這個問題,就必定會有解決方案,那就是建立一個配置中心,專門用於管理系統的全部配置,也就是咱們將全部配置文件放到統一的地方進行管理。git
咱們知道,SpringCloud 就是爲了簡化開發而生的,所以 SpringCloud 爲咱們集成了配置中心——Spring Cloud Config 組件。github
Spring Cloud Config 簡介spring
Spring Cloud Config 是一個高可用的分佈式配置中心,它支持將配置存放到內存(本地),也支持將其放到 Git 倉庫進行統一管理(本文主要探討和 Git 的融合)。數據庫
建立配置中心bootstrap
建立配置中心通常分爲如下幾個步驟:瀏覽器
1.建立 Git 倉庫。安全
本文爲了演示實例,已經建立好了用於存放配置文件的 Git 倉庫,點擊這裏訪問。app
2.建立配置中心。curl
在原有工程建立一個 moudle,命名爲 config,在 pom.xml 加入配置中心的依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-eureka</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-config-server</artifactId> </dependency>
建立啓動類 Application.java:
@SpringBootApplication @EnableEurekaClient @EnableConfigServer public class Application { public static void main(String[] args) { SpringApplication.run(Application.class,args); } }
注意,要加入 @EnableConfigServer 註解,不然配置中心是沒法開啓的。
建立 application.yml 並增長以下內容:
server: port: 8888 spring: application: name: config profiles: active: dev cloud: config: server: git: uri: https://github.com/lynnlovemin/SpringCloudLesson.git #配置git倉庫地址 searchPaths: 第09課/config #配置倉庫路徑 username: ****** #訪問git倉庫的用戶名 password: ****** #訪問git倉庫的用戶密碼 label: master #配置倉庫的分支 eureka: instance: hostname: ${spring.cloud.client.ipAddress} instanceId: ${spring.cloud.client.ipAddress}:${server.port} client: serviceUrl: defaultZone: http://localhost:8761/eureka/
注意這裏出現了前面課程沒有出現過的新配置: eureka.instance.hostname 和 eureka.instance.instanceId,咱們能夠經過一個測試來看這兩個配置的做用。
首先分別啓動註冊中心 eurekaserver 和配置中心 config,瀏覽器訪問:http://localhost:8761,咱們能夠看到以下界面:
能夠看到箭頭所指向的位置是以 IP:端口形式呈現的,如今咱們去掉這兩個配置從新啓動配置中心 config,再次訪問:http://localhost:8761,能夠看到:
因而可知,它默認是以 ip:application_name:端口呈現的。
在實際項目中,建議你們都寫成上述配置,不然若是經過 K8S 或 Docker 部署系統,可能會出現問題,具體緣由將在第16課提到。
經過上述過程,配置服務中心已經建立完成,啓動它而且訪問地址:http://localhost:8888/config/dev,便可看到:
3.修改各個服務配置。
咱們建立配置中心的目的就是爲了方便其餘服務進行統一的配置管理,所以,還須要修改各個服務。
以服務提供者 eurekaclient 爲例,按照如下步驟進行操做。
在 pom.xml 加入配置中心依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-config</artifactId> </dependency>
在 resources 下新建 bootstrap.yml 並刪除 application.yml(注意:這裏不是 application.yml,而是 bootstrap.yml):
spring: application: name: eurekaclient profiles: active: dev cloud: config: profile: dev #指定配置環境,配置文件若是是多環境則取名相似:config-dev.yml name: eurekaclient #指定配置文件名字(多個配置文件以英文逗號隔開) label: master #git倉庫分支名 discovery: enabled: true serviceId: config #鏈接的配置中心名字(applicaiton.name) eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/
在配置中心配置的 Git 倉庫相應路徑下建立配置文件 eurekaclient.yml(本實例爲第09課/config):
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8763 spring: application: name: eurekaclient
咱們依次啓動註冊中心、配置中心和服務提供者 eurekaclient,能夠看到 eurekaclient 的監聽端口爲8763,而後修改 eurekaclient.yml 的 server.port 爲8764,從新啓動 eurekaclient,能夠看到其監聽端口爲8764,說明 eurekaclient 成功從 Git 上拉取了配置。
配置自動刷新
咱們注意到,每次修改配置都須要從新啓動服務,配置纔會生效,這種作法也比較麻煩,所以咱們須要一個機制,每次修改了配置文件,各個服務配置自動生效,Spring Cloud 給咱們提供瞭解決方案。
手動刷新配置
咱們先來看看如何經過手動方式刷新配置。
1.在 eurekaclient 工程的 pom.xml 添加依賴:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2.修改遠程 Git 倉庫的配置文件 eurekaclient.yml:
eureka: client: serviceUrl: defaultZone: http://localhost:8761/eureka/ server: port: 8764 spring: application: name: eurekaclient management: security: #關閉安全驗證,不然訪問refresh端點時會提示權限不足 enabled: false
3.在 HelloController 類加入 @RefeshScope 依賴:
@RestController @RefreshScope public class HelloController { @Value("${server.port}") private int port; @RequestMapping("index") public String index(){ return "Hello World!,端口:"+port; } }
以上步驟就集成了手動刷新配置。下面開始進行測試。
1.依次啓動註冊中心,配置中心,客戶端;
2.訪問地址:http://localhost:8763/index,便可看到:
3.修改 Git 倉庫遠程配置文件 eurekaclient.yml 的端口爲8764;
4.從新訪問2的地址,咱們發現端口未發生改變;
5.POST 方式請求地址:http://localhost:8763/refresh,如:curl -X POST http://localhost:8763/refresh,能夠的客戶端控制檯看到以下日誌信息:
說明 refresh 端點已請求配置中心刷新配置。 6.再次訪問2的地址,能夠看到:
咱們發現端口已發生改變,說明刷新成功!
自動刷新配置
前面咱們講了經過 /refresh 端點手動刷新配置,若是每一個微服務的配置都須要咱們手動刷新,代價無疑是巨大的。不只如此,隨着系統的不斷擴張,維護也愈來愈麻煩。所以,咱們有必要實現自動刷新配置。
自動刷新配置原理
利用 Git 倉庫的 WebHook,能夠設置當有內容 Push 上去後,則經過 HTTP 的 POST 遠程請求指定地址。
利用消息隊列如 RabbitMQ、Kafka 等自動通知到每一個微服務(本文以 RabbitMQ 爲例講解)。
實現步驟
下面咱們就來實現自動刷新配置。
1.安裝 RabbitMQ(安裝步驟省略,請自行百度)
2.在 eurekaclient 加入以下依賴:
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-bus-amqp</artifactId> </dependency>
3.在 bootstrap.yml 添加如下內容:
spring: rabbitmq: host: localhost port: 5672 username: guest password: guest
5.POST 方式請求:http://localhost:8763/bus/refresh,能夠看到配置已被刷新,實際項目中,咱們會單首創建一個工程用以刷新配置,請求這個地址後,能夠發現全部加入了 RefreshScope 和 actuator 依賴的工程都會被刷新配置。
6.利用 Git 的 WebHook,實現自動刷新,如圖:
設置好刷新 URL 後,點擊提交。之後每次有新的內容被提交後,會自動請求該 URL 實現配置的自動刷新。