1.熔斷器 Hystrix
1.1. 雪崩效應(yīng)
在微服務(wù)架構(gòu)中通常會有多個服務(wù)層調(diào)用,基礎(chǔ)服務(wù)的故障可能會導致級聯(lián)故障,進而造成整個系統(tǒng)不可用的情況,這種現(xiàn)象被稱為服務(wù)雪崩效應(yīng)。服務(wù)雪崩效應(yīng)是一種因“服務(wù)提供者”的不可用導致“服務(wù)消費者”的不可用,并將不可用逐漸放大的過程。
如果下圖所示:A 作為服務(wù)提供者,B 為 A 的服務(wù)消費者,C 和 D 是 B的服務(wù)消費者。A
不可用引起了 B 的不可用,并將不可用像滾雪球一樣放大到 C 和 D時,雪崩效應(yīng)就形成了。

如何避免產(chǎn)生這種雪崩效應(yīng)呢?我們可以使用 Hystrix 來實現(xiàn)熔斷器。
1.1.1 雪崩效應(yīng)的常見場景
?硬件故障:如服務(wù)器宕機,機房斷電,光纖被挖斷等
? ? ? ?多機房容災,異地多活
?流量激增:如異常流量,重試加大流量等
? ? ? ?服務(wù)擴容,流量控制,限流、關(guān)閉等
?緩存穿透:一般發(fā)生在重啟應(yīng)用,所有緩存失效時,以及短時間內(nèi)大量緩存失效時。大量的緩存不命中,使請求直接全部來到后端服務(wù),造成服務(wù)的超負載運行,引起服務(wù)不可用
? ? ???緩存預熱,緩存異步加載
?程序BUG:如程序邏輯導致內(nèi)存泄漏
? ? ? ?修改程序bug,及時釋放資源。
?同步等待:服務(wù)間采用同步調(diào)用模式,同步等待造成資源的耗盡
? ? ???MQ解耦,不可用服務(wù)調(diào)用快速失敗。
1.2. 什么是 Hystrix
Hystrix [h?st'r?ks]的中文含義是豪豬, 因其背上長滿了刺,而擁有自我保護能力。

Hystrix 能使你的系統(tǒng)在出現(xiàn)依賴服務(wù)失效的時候,通過隔離系統(tǒng)所依賴的服務(wù),防止服務(wù)級聯(lián)失敗,同時提供失敗回退機制,更優(yōu)雅地應(yīng)對失效,并使你的系統(tǒng)能更快地從異常中恢復。了解熔斷器模式請看下圖:

1.3. 快速體驗
Feign 本身支持 Hystrix,不需要額外引入依賴。
(1)修改 ktc_qa 模塊的 application.yml ,開啟 hystrix
feign: # 開啟熔斷器
? hystrix:
? ? enabled: true
(2)在 com.ktc.qa.client 包下創(chuàng)建 impl包,包下創(chuàng)建熔斷實現(xiàn)類,實現(xiàn)自接口 LabelClient
package com.ktc.qa.client.impl;
import com.ktc.qa.client.LabelClient;
import entity.Result;
import entity.StatusCode;
import org.springframework.stereotype.Component;
@Component? ? ? ? ? ? ? //把該組件注入到spring容器中
public class LabelClientImpl implements LabelClient {
? ? @Override
? ? public Result findById(String id) {
? ? ? ? return new Result(false, StatusCode.ERROR,"熔斷器生效啦.....");
? ? }
}
(3)修改 LabelClient 的注解
package com.ktc.qa.client;
import com.ktc.qa.client.impl.LabelClientImpl;
import entity.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient(value = "ktc-base",fallback = LabelClientImpl.class)//調(diào)用微服的名稱
public interface LabelClient {
? ? @RequestMapping(value = "/label/{id}", method = RequestMethod.GET)
? ? public Result findById(@PathVariable("id") String id);
}
(4)測試運行
重新啟動問答微服務(wù),測試看熔斷器是否運行 。
2.微服務(wù)網(wǎng)關(guān) Zuul
2.1. 為什么需要微服務(wù)網(wǎng)關(guān)
不同的微服務(wù)一般有不同的網(wǎng)絡(luò)地址,而外部的客戶端可能需要調(diào)用多個服務(wù)的接口才能完成一個業(yè)務(wù)需求。比如一個電影購票的收集APP,可能會調(diào)用電影分類微服務(wù),用戶微服務(wù),支付微服務(wù)等。如果客戶端直接和微服務(wù)進行通信,會存在以下問題:
?客戶端會多次請求不同微服務(wù),增加客戶端的復雜性
?存在跨域請求,在一定場景下處理相對復雜
?認證復雜,每一個服務(wù)都需要獨立認證
?難以重構(gòu),隨著項目的迭代,可能需要重新劃分微服務(wù),如果客戶端直接和微服務(wù)通信,那么重構(gòu)會難以實施
上述問題,都可以借助微服務(wù)網(wǎng)關(guān)解決。微服務(wù)網(wǎng)關(guān)是介于客戶端和服務(wù)器端之間的中間層,所有的外部請求都會先經(jīng)過微服務(wù)網(wǎng)關(guān)。
2.2. 什么是 Zuul
Zuul 是 Netflix 開源的微服務(wù)網(wǎng)關(guān),他可以和 Eureka,Ribbon,Hystrix等組件配合使用。Zuul組件的核心是一系列的過濾器,這些過濾器可以完成以下功能:
??身份認證和安全: 識別每一個資源的驗證要求,并拒絕那些不符的請求
審查與監(jiān)控:
??動態(tài)路由:動態(tài)將請求路由到不同后端集群?
??壓力測試:逐漸增加指向集群的流量,以了解性能
??負載分配:為每一種負載類型分配對應(yīng)容量,并棄用超出限定值的請求
??靜態(tài)響應(yīng)處理:邊緣位置進行響應(yīng),避免轉(zhuǎn)發(fā)到內(nèi)部集群
??多區(qū)域彈性:跨域 AWS Region 進行請求路由,旨在實現(xiàn) ELB(ElasticLoadBalancing)使用多樣化
Spring Cloud 對 Zuul 進行了整合和增強。
使用 Zuul 后,架構(gòu)圖演變?yōu)橐韵滦问剑?/p>

2.3. Zuul 路由轉(zhuǎn)發(fā)
2.3.1. 管理后臺微服務(wù)網(wǎng)關(guān)
(1)創(chuàng)建子模塊 ktc_manager,pom.xml 引入 eureka-client 和 zuul的依賴
<!--Eureka客戶端依賴-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--微服務(wù)網(wǎng)關(guān)Zuul依賴-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
(2)創(chuàng)建 application.yml
server:
? port: 9011
spring:
? application:
? ? name: ktc-manager
eureka:
? client:
? ? service-url:
? ? ? defaultZone: http://127.0.0.1:10101/eureka
? instance:
? ? prefer-ip-address: true #使用IP注冊而不是主機名(注冊多個微服時用IP區(qū)分)
zuul:
? routes:
? ? ktc-base:
? ? ? path: /base/**
? ? ? serviceId: ktc-base
? ? ktc-qa:
? ? ? path: /qa/**
? ? ? serviceId: ktc-qa
? ? ktc-user:? ? ? ? ? ? ? #路由Key
? ? ? path: /user/**? ? ? ? #配置請求 URL 的請求規(guī)則
? ? ? serviceId: ktc-user? #指定 Eureka 注冊中心中的服務(wù) id
(3)編寫啟動類
package com.ktc.manager;
import org.apache.catalina.Manager;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy? ? ? ? ? ? ? ? //開啟網(wǎng)關(guān)代理
@EnableEurekaClient //eureka客戶端
public class ManagerApplication {
? ? public static void main(String[] args) {
? ? ? ? SpringApplication.run(ManagerApplication.class);
? ? }
}
2.3.2. 網(wǎng)站前臺的微服務(wù)網(wǎng)關(guān)
(1)創(chuàng)建子模塊 ktc_web,pom.xml 引入依賴 zuul
<!--Eureka客戶端依賴-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--微服務(wù)網(wǎng)關(guān)Zuul依賴-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
(2)創(chuàng)建 application.yml
server:
? port: 9012
spring:
? application:
? ? name: ktc-web
eureka:
? client:
? ? service-url:? # eureka的注冊地址
? ? ? defaultZone: http://127.0.0.1:10101/eureka
? instance:
? ? prefer-ip-address: true
zuul:
? routes:? ? ? #配置網(wǎng)關(guān)路由轉(zhuǎn)發(fā)
? ? ktc-base:? #基礎(chǔ)微服
? ? ? path: /base/**? ? ? ? #配置請求 URL 的請求規(guī)則
? ? ? serviceId: ktc-base? #注冊到eureka中的微服名稱
? ? ktc-qa:
? ? ? path: /qa/**
? ? ? serviceId: ktc-qa
? ? ktc-user:
? ? ? path: /user/**
? ? ? serviceId: ktc-user
(3)編寫啟動類
package com.ktc.web;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
@SpringBootApplication
@EnableZuulProxy? ? ? ? ? ? //開啟網(wǎng)關(guān)代理
@EnableEurekaClient //eureka客戶端
public class WebApplication {
? ? public static void main(String[] args) {
? ? ? ? SpringApplication.run(WebApplication.class);
? ? }
}
2.4. Zuul 過濾器
2.4.1. Zuul 過濾器快速體驗
我們現(xiàn)在在 ktc_web 創(chuàng)建一個簡單的 zuul 過濾器
package com.ktc.web;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.stereotype.Component;
@Component
public class WebFilter extends ZuulFilter {
? ? /**
? ? * 執(zhí)行時機
? ? * pre:? ? 在進入微服網(wǎng)關(guān)之間執(zhí)行
? ? * route:? 在執(zhí)行微服務(wù)網(wǎng)關(guān)時執(zhí)行
? ? * post:? ? 在執(zhí)行微服務(wù)網(wǎng)關(guān)之后執(zhí)行
? ? * error:? 在執(zhí)行微服務(wù)出錯執(zhí)行
? ? * @return
? ? */
? ? @Override
? ? public String filterType() {
? ? ? ? return "pre";
? ? }
? ? /**
? ? * 執(zhí)行順序
? ? * 數(shù)字越大,優(yōu)先級越低
? ? * @return
? ? */
? ? @Override
? ? public int filterOrder() {
? ? ? ? return 0;
? ? }
? ? /**
? ? * 是否執(zhí)行該過濾器
? ? * true:執(zhí)行
? ? * false:不執(zhí)行
? ? * @return
? ? */
? ? @Override
? ? public boolean shouldFilter() {
? ? ? ? return true;
? ? }
? ? /**
? ? * 過濾器執(zhí)行邏輯
? ? * @return 返回null代表放行,訪問對應(yīng)的微服務(wù)
? ? * @throws ZuulException
? ? */
? ? @Override
? ? public Object run() throws ZuulException {
? ? ? ? System.out.println("Zuul過濾器生效啦!");
? ? ? ? return null;
? ? }
}
啟動 ktc
_web 會發(fā)現(xiàn)過濾器已經(jīng)執(zhí)行
filterType:返回一個字符串代表過濾器的類型,在 zuul中定義了四種不同生命周期的過濾器類型,具體如下:
??pre:在請求路由之前被調(diào)用
??route:在路由請求時候被調(diào)用
??post:在route和error過濾器之后被調(diào)用
??error:處理請求時發(fā)生錯誤時被調(diào)用
??filterOrder:通過int值來定義過濾器的執(zhí)行順序
??shouldFilter:返回一個boolean類型來判斷該過濾器是否要執(zhí)行,true:執(zhí)行,false:不執(zhí)行
2.4.2. 管理后臺過濾器實現(xiàn) Token 校驗
修改 ktc_manager 的過濾器, 因為是管理后臺使用,所以需要在過濾器中對token 進行驗證。
(1)ktc_manager 引入 ktc_common 依賴 ,因為需要用到其中的 JWT工具類
<dependency>
? ? <groupId>com.ktc</groupId>
? ? <artifactId>ktc_common</artifactId>
? ? <version>1.0-SNAPSHOT</version>
</dependency>
(2)修改 ktc_manager 配置文件 application.yml
server:
? port: 9011
spring:
? application:
? ? name: ktc-manager
eureka:
? client:
? ? service-url:
? ? ? defaultZone: http://127.0.0.1:10101/eureka
? instance:
? ? prefer-ip-address: true #使用IP注冊而不是主機名(注冊多個微服時用IP區(qū)分)
zuul:
? routes:
? ? ktc-article:
? ? ? path: /article/**
? ? ? serviceId: ktc-article
? ? ktc-gathering:
? ? ? path: /gathering/**
? ? ? serviceId: ktc-gathering
? ? ktc-recruit:? ? ? ? ? ? ? #用戶微服
? ? ? path: /recruit/**? ? ? ? #配置請求 URL 的請求規(guī)則
? ? ? serviceId: ktc-recruit? #指定 Eureka 注冊中心中的服務(wù) id
? ? ktc-user:
? ? ? path: /user/**? ? ? ? #配置請求 URL 的請求規(guī)則
? ? ? serviceId: ktc-user? #指定 Eureka 注冊中心中的服務(wù) id
jwt:
? config:
? ? key: dfbz_? ? ? #token秘鑰
? ? prefix: dfbz_
(3)修改 ktc_manager 的啟動類,添加 bean
@Bean
public JwtUtil jwtUtil(){
? ? return new JwtUtil();
}
(4)ktc_manager 編寫過濾器類
package com.ktc.manager;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import io.jsonwebtoken.Claims;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import util.JwtUtil;
import javax.servlet.http.HttpServletRequest;
@Component
public class ManagerFilter extends ZuulFilter {
? ? @Autowired
? ? private Environment env;
? ? @Autowired
? ? private JwtUtil jwtUtil;
? ? @Override
? ? public String filterType() {
? ? ? ? return "pre";
? ? }
? ? @Override
? ? public int filterOrder() {
? ? ? ? return 0;
? ? }
? ? @Override
? ? public boolean shouldFilter() {
? ? ? ? return true;
? ? }
? ? @Override
? ? public Object run() throws ZuulException {
? ? ? ? RequestContext context = RequestContext.getCurrentContext();
? ? ? ? HttpServletRequest request = context.getRequest();
? ? ? ? // 獲取請求頭數(shù)據(jù)
? ? ? ? String auth = request.getHeader("auth");
? ? ? ? String prefix = env.getProperty("jwt.config.prefix");
? ? ? ? // 設(shè)置響應(yīng)數(shù)據(jù)的格式
? ? ? ? context.getResponse().setContentType("text/html;charset=utf8");
? ? ? ? if (auth == null || !auth.startsWith(prefix)) {
? ? ? ? ? ? //不是管理員
? ? ? ? ? ? //中止請求
? ? ? ? ? ? context.setSendZuulResponse(false);
? ? ? ? ? ? //設(shè)置正確響應(yīng)內(nèi)容
? ? ? ? ? ? context.setResponseBody("無權(quán)訪問");
? ? ? ? ? ? return null;
? ? ? ? }
? ? ? ? //獲取token字符串
? ? ? ? String token = auth.substring(prefix.length());
? ? ? ? Claims claims = jwtUtil.parseJWT(token);
? ? ? ? if (!claims.get("role").toString().equals("admin")) {
? ? ? ? ? ? //中止請求
? ? ? ? ? ? context.setSendZuulResponse(false);
? ? ? ? ? ? //設(shè)置正確響應(yīng)內(nèi)容
? ? ? ? ? ? context.setResponseBody("你不是管理員哦");
? ? ? ? }
? ? ? ? return null;
? ? }
}
測試訪問查詢文章列表:
URL:http://localhost:9011/article/article
method:GET
3.集中配置組件 SpringCloudConfig
3.1. SpringCloudConfig 簡介
在分布式系統(tǒng)中,由于服務(wù)數(shù)量巨多,為了方便服務(wù)配置文件統(tǒng)一管理,實時更新,所以需要分布式配置中心組件。在Spring Cloud 中,有分布式配置中心組件 spring cloud config,它支持配置服務(wù)放在配置服務(wù)的內(nèi)存中(即本地),也支持放在遠程 Git倉庫中。在 spring cloud config 組件中,分兩個角色,
一是 config server,
二是config client。
Config Server是一個可橫向擴展、集中式的配置服務(wù)器,它用于集中管理應(yīng)用程序各個環(huán)境下的配置,默認使用 Git 存儲配置文件內(nèi)容,也可以使用 SVN存儲,或者是本地文件存儲。Config Client 是 Config Server 的客戶端,用于操作存儲在 Config Server中的配置內(nèi)容。微服務(wù)在啟動時會請求 Config Server獲取配置文件的內(nèi)容,請求到后再啟動容器。詳細內(nèi)容看在線文檔:https://springcloud.cc/spring-cloud-config.html
3.2. 配置服務(wù)端
3.2.1. 將配置文件提交到碼云
使用 GitHub時,國內(nèi)的用戶經(jīng)常遇到的問題是訪問速度太慢,有時候還會出現(xiàn)無法連接的情況。如果我們希望體驗Git 飛一般的速度,可以使用國內(nèi)的 Git 托管服務(wù) ——碼云(gitee.com)。
GitHub 相比,碼云也提供免費的 Git倉庫。此外,還集成了代碼質(zhì)量檢測、項目演示等功能。對于團隊協(xié)作開發(fā),碼云還提供了項目管理、代碼托管、文檔管理的服務(wù)。
步驟:
(1)瀏覽器打開 gitee.com,注冊用戶 ,注冊后登陸碼云管理控制臺

(2)創(chuàng)建項目 ktc-config (點擊右上角的加號 ,下拉菜單選擇創(chuàng)建項目)
(3)上傳配置文件,將 ktc_base 工程的 application.yml 改名為base-dev.yml 后
上傳

可以通過拖拽的方式將文件上傳上去

上傳成功后列表可見

可以再次編輯此文件

文件命名規(guī)則:{application}-{profile}.yml 或{application}-{profile}.properties application 為應(yīng)用名稱 profile 指的開發(fā)環(huán)境(用于區(qū)分開發(fā)環(huán)境,測試環(huán)境、生產(chǎn)環(huán)境等)
(4)復制 git 地址 ,備用

地址為:https://gitee.com/gz_dfbz/KTC.git
3.2.2. 配置中心微服務(wù)
(1)創(chuàng)建工程模塊 配置中心微服務(wù) ktc_config ,pom.xml 引入依賴
<!--SpringCloudConfig依賴-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-config-server</artifactId>
</dependency>
(2)創(chuàng)建啟動類 ConfigServerApplication
package com.ktc.config;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.config.server.EnableConfigServer;
@EnableConfigServer? ? ? ? //開啟SpringCloudConfig集中配置服務(wù)器
@SpringBootApplication
public class ConfigApplication {
? ? public static void main(String[] args) {
? ? ? ? SpringApplication.run(ConfigApplication.class);
? ? }
}
(3)編寫配置文件 application.yml
server:
? port: 10102
spring:
? application:
? ? name: ktc-config
? cloud:
? ? config:
? ? ? server:
? ? ? ? git:
? ? ? ? ? uri: 你的碼云項目鏈接地址
(4)瀏覽器測試:http://localhost:10102/base-dev.yml 可以看到配置內(nèi)容
3.3. 配置客戶端
(1)在 ktc_base 工程添加依賴
<!--config集中配置客戶端-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-starter-config</artifactId>
</dependency>
(2)添加 bootstrap.yml ,刪除 application.yml
spring:
? cloud:
? ? config:
? ? ? uri: http://127.0.0.1:10102? # 配置中心服務(wù)端地址
? ? ? name: base? ? ? # 配置文件的應(yīng)用名稱
? ? ? profile: dev? ? # 配置文件的環(huán)境名稱
? ? ? label: master? # 在遠程倉庫的分支名稱
(3)測試: 啟動工程 ktc
_eureka ktc_config ktc_base,看是否可以正常運行
4.消息總線 SpringCloudBus
4.1. SpringCloudBus 簡介
如果我們更新碼云中的配置文件,那客戶端工程是否可以及時接受新的配置信息呢?我們現(xiàn)在來做有一個測試,修改一下碼云中的配置文件中 mysql 的端口,然后測試http://localhost:9001/label數(shù)據(jù)依然可以查詢出來,證明修改服務(wù)器中的配置并沒有更新立刻到工程,只有重新啟動程序才會讀取配置。那我們?nèi)绻朐诓恢貑⑽⒎?wù)的情況下更新配置如何來實現(xiàn)呢? 我們使用SpringCloudBus 來實現(xiàn)配置的自動更新。
4.1.1 Bus總線刷新流程

4.2. 代碼實現(xiàn)
4.2.1. 配置服務(wù)端
(1)修改 ktc_config 工程的 pom.xml,引用依賴
<!--消息總線bus-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-bus</artifactId>
</dependency>
<!--rabbitmq-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
(2)修改 application.yml ,添加配置
server:
? port: 10102
spring:
? application:
? ? name: ktc-config
? cloud:
? ? config:
? ? ? server:
? ? ? ? git:
? ? ? ? ? uri: https://gitee.com/gz_dfbz/KTC.git
? rabbitmq:
? ? host: 192.168.12.137
management: #暴露觸發(fā)消息總線的地址
? endpoints:
? ? web:
? ? ? exposure:
? ? ? ? include: bus-refresh
4.2.2. 配置客戶端
我們還是以基礎(chǔ)模塊為例,加入消息總線
(1)修改 ktc_base 工程 ,引入依賴
<!--消息總線bus依賴-->
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-bus</artifactId>
</dependency>
<dependency>
? ? <groupId>org.springframework.cloud</groupId>
? ? <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
<dependency>
? ? <groupId>org.springframework.boot</groupId>
? ? <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
(2)在碼云的配置文件中添加配置 rabbitMQ 的地址:
rabbitmq:
host: 192.168.12.133
(3)啟動 ktc_eureka 、ktc_config 和 ktc_base看是否正常運行
(4)修改碼云上的配置文件 ,將數(shù)據(jù)庫連接 IP 改為 127.0.0.1,在本地部署一份數(shù)據(jù)庫。
(5)postman 測試 Url: http://127.0.0.1:10102/actuator/bus-refresh Method:post
(6)再次觀察輸出的數(shù)據(jù)是否是讀取了本地的 mysql 數(shù)據(jù)
4.2.3. 自定義配置的讀取
(1)修改碼云上的配置文件,增加自定義配置
dfbz:
? ? config:
? ? ? ? info: 測試bus總線刷新
(2)在 ktc_base 工程中新建 controller
@Value("${dfbz.config.info}")
private String info;
?
@RequestMapping(value ="/testBus", method = RequestMethod.GET)
public Result testBus(){
?
return new Result(true,StatusCode.OK,"查詢成功",info);
}
(3)運行測試看是否能夠讀取配置信息 ,OK
(4)修改碼云上的配置文件中的自定義配置
dfbz:
? ? config:
? ? ? ? info: 測試bus總線刷新-----2
(5)通 過 postman 測 試 Url: http://127.0.0.1:12000/actuator/bus-refresh
Method:post
測試后觀察,發(fā)現(xiàn)并沒有更新信息。
這是因為我們的 controller 少了一個注解@RefreshScope 此注解用于刷新配置
@RestController
@RequestMapping("/label")
@CrossOrigin
@RefreshScope// 刷新自定義配置
publicclassLabelController{
添加后再次進行測試 。
4.2.4. 完成KTC工程的配置集中管理
(1)將每一個工程的配置文件提取出來,重命名
(2)將這些文件上傳到碼云
(3)修改每一個微服務(wù)工程,pom.xml 中添加依賴
<!--config集中配置客戶端-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
?
<!--消息總線bus依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-bus</artifactId>
</dependency>
?
<!--rabbitmq依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
</dependency>
?
<!--實時更新-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
(4)刪除每一個微服務(wù)的 application.yml
(5)為每一個微服務(wù)添加 bootstrap.yml (參考 ktc_base 工程)
(6)修改碼云上的配置文件添加 rabbitmq 地址
rabbitmq:
? ? host: 192.168.12.133