前言敘述:
Spring Cloud Config 配置服務(wù)端與配置客戶端诽表,配置服務(wù)端Config Server 主要的作用集中保管與獲取配置信息;
配置客戶端的配置信息(大部分)放置在配置服務(wù)端拐辽,配置客戶端本地不存放配置信息;
配置客戶端啟動后會首先去配置服務(wù)端取獲取基本的配置信息(http://uri/{spring.cloud.config.name}/{spring.cloud.config.profile},uri為通過配置的spring.cloud.config.uri或者通過注冊中心的spring.cloud.config.discovery.serviceId獲取注冊的uri)
Gateway 作為網(wǎng)關(guān)致扯,同時作為Config Client與Eureka Client鼻吮,Config Server與Config Client均作為Eureka Client;
網(wǎng)關(guān)能攔截過濾通過網(wǎng)關(guān)的請求筹裕,并且可以處理請求醋闭;
注冊中心集中提供注冊在其上的服務(wù);
配置中心提供配置信息服務(wù)朝卒,開放的endpoint是(不用手動配置证逻,bus-refresh需要配置):http://配置服務(wù)端ip:配置服務(wù)端port/{name}/{profile},并且nio實現(xiàn)實時訪問實時獲取本地文件最新配置信息抗斤;
配置客戶端的配置刷新需要:1依賴actuator囚企;2開放刷新endpoint:refresh;3依賴注解@RefreshScope(實現(xiàn)特征Bean的屬性更新)丈咐;4觸發(fā)更新;
需求分析:
1.原始的application.yml配置文件 spring.profiles.active 可以指定用哪個具體的配置文件洞拨,現(xiàn)在采用了Config Server能不能實現(xiàn)通過配置profile實現(xiàn)Config Client的配置文件的整體切換扯罐,且不用重啟呢?
2.注解@RefreshScope能實現(xiàn)屬性的更新烦衣,但是能不能實現(xiàn)數(shù)據(jù)源的更新呢歹河?
解決方案:
首先分析項目框架的各個角色的主要功能
1.配置服務(wù)端主要用來集中保管與提供最新的配置信息,也就是說配置服務(wù)端的功能很單一花吟,簡單說native模式就是一個本地文件系統(tǒng)秸歧,然后開放訪問api,保證最新衅澈,然后就沒了键菱,至于其他模式(git/svn/jdbc),應(yīng)該亦復(fù)如是今布,不外乎是提供bus-refresh進(jìn)行更新本地文件信息经备,訪問時提供最新的配置信息罷了,總體來說設(shè)計很單純部默;
2.配置客戶端侵蒙,就是去配置服務(wù)端獲取配置信息,于本地系統(tǒng)區(qū)別就是獲取資源的方式不同傅蹂,但是主體配置放在bootstrap中纷闺,配置客戶端啟動或者手動更新請求時會向配置的配置服務(wù)端的資源地址發(fā)起請求;
3.網(wǎng)關(guān)與注冊中心的功能在前言敘述中已經(jīng)說過了份蝴,不復(fù)多言犁功;
其次解決思路
一.配置文件的整體切換,不外乎有兩種方案:a.修改配置服務(wù)端的對應(yīng)的配置文件婚夫;b.修改配置客戶端的請求地址浸卦;
配置客戶端的配置不改變,直接修改對應(yīng)的配置服務(wù)端對應(yīng)配置文件的配置內(nèi)容案糙,不免改動動靜太大了限嫌,舉個例子:配置客戶端請求的配置文件時application-dev.yml,現(xiàn)在的做法是直接在配置服務(wù)端修改application-dev.yml,然后更新配置客戶端取最新的配置文件即可侍筛,會不會發(fā)現(xiàn)這種的修改真是太粗魯了萤皂;
配置客戶端的配置不改變,然后在配置服務(wù)端有各種配置文件application-dev.yml匣椰,application-test.yml裆熙,application-prod.yml等等,然后再通過配置dev/test/prod等然后通過更新配置客戶端,自動實現(xiàn)配置客戶端配置文件的全文切換入录;然后怎么辦呢蛤奥?一開始的思路,配置服務(wù)端有沒有這樣的配置呢僚稿?分析一下會發(fā)現(xiàn)凡桥,配置服務(wù)端的功能定位很單純,似乎不能做到直接配置進(jìn)行切換蚀同,但是別忘了網(wǎng)關(guān)的存在缅刽,通過網(wǎng)關(guān)攔截過濾處理請求不就好了。
最終的解決方案是蠢络,通過網(wǎng)關(guān)進(jìn)行配置請求的過濾處理即可衰猛,當(dāng)然需要把網(wǎng)關(guān)也作為Config Client并且結(jié)合注解@RefreshScope實現(xiàn)具體配置客戶端的請求的轉(zhuǎn)發(fā)配置獲取,然后對配置請求路徑進(jìn)行修改即可刹孔;
注意:
1.所有的配置請求都寫在了網(wǎng)關(guān)的配置文件里髓霞,所以更新配置客戶端前需要先更新網(wǎng)關(guān)的配置文件
2.網(wǎng)關(guān)的路由都是在請求到達(dá)前先寫入內(nèi)存的卦睹,所以需要在更新時重寫路由信息,也就是需要利用注解@RefreshScope在更新網(wǎng)關(guān)配置時刷新路由
3.配置客戶端不能再直接配置配置服務(wù)端的uri或者serviceId方库,因為需要網(wǎng)關(guān)的過濾處理结序,所以全改成網(wǎng)關(guān)的uri或者serviceId
二.上文已經(jīng)實現(xiàn)了配置文件的更新切換,數(shù)據(jù)源的配置信息自然也能獲取到薪捍,這就需要分析切換數(shù)據(jù)源的關(guān)鍵問題所在笼痹。
我們使用的Spring框架配喳,所有的東西都是和Spring整合酪穿,都交給Spring容器進(jìn)行統(tǒng)一管理,Dao層用的Mybatis也不例外晴裹。
最直接也最簡單的思路就是從Spring容器取出來對應(yīng)的數(shù)據(jù)源對應(yīng)的Bean被济,然后直接進(jìn)行數(shù)據(jù)源的替換即可。
思路很重要~方向?qū)α酥涣祝椭皇欠椒ǖ膯栴}
注:
在配置服務(wù)端會存在配置文件的merge問題,即application.yml與application-dev.yml文件的泌绣,相同的屬性訪問后者時以后者為準(zhǔn)(覆蓋)钮追,前者有而后者沒有的屬性,訪問后者時也會有(合并在一起)阿迈;作用:前者可以存放共同的配置
application-prod.yml與application-dev.yml配置信息不會相互影響
application-dev.yml與application-dev-test.yml配置信息元媚,application-dev-test只會合并application-dev一級,不會繼續(xù)合并application
更新:
本著模塊職責(zé)單一明確的原則:網(wǎng)關(guān)最好不做配置相關(guān)信息的轉(zhuǎn)發(fā)與處理
配置客戶端也不應(yīng)該對配置做過多的處理,最好的方式是在配置服務(wù)端處理
處理思路分析:配置服務(wù)端攔截配置客戶端的配置更新請求刊棕,然后判斷請求文件里的spring.profiles.active屬性是否與請求的profile一致炭晒,不一致時對請求地址進(jìn)行替換即可。(Spring Cloud Config Server 基于Spring Mvc實現(xiàn)的可以實現(xiàn)請求的攔截處理)