前言
在這篇文章介紹并記錄關(guān)于Spring Cloud 服務(wù)容錯和Hystrix 的簡單應(yīng)用。
為什么使用Hystrix
在微服務(wù)架構(gòu)中砍鸠,我們將系統(tǒng)拆分為很多個服務(wù),各個服務(wù)之間通過注冊與訂閱的方式相互依賴耕驰,由于各個服務(wù)都是在各自的進(jìn)程中運(yùn)行爷辱,就有可能由于網(wǎng)絡(luò)原因或者服務(wù)自身的問題導(dǎo)致調(diào)用故障或延遲,隨著服務(wù)的積壓朦肘,可能會導(dǎo)致服務(wù)崩潰饭弓。為了解決這一系列的問題,斷路器等一系列服務(wù)保護(hù)機(jī)制出現(xiàn)了媒抠。
例如
復(fù)雜分布式系統(tǒng)通常有很多依賴弟断,如果一個應(yīng)用不能對來自依賴 故障進(jìn)行隔離,那么應(yīng)用本身就處在被拖垮的風(fēng)險中趴生。在一個高流量的網(wǎng)站中阀趴,某個單一后端一旦發(fā)生延遲,將會在數(shù)秒內(nèi)導(dǎo)致 所有應(yīng)用資源被耗盡(一個臭雞蛋影響一籃筐)
如秒殺苍匆、搶購刘急、雙十一等場景,在某一時間點(diǎn)會有爆發(fā)式的網(wǎng)絡(luò)流量涌入浸踩,如果沒有好的網(wǎng)絡(luò)流量限制叔汁,任由流量壓到后臺服務(wù)實(shí)例,很有可能造成資源耗盡检碗,服務(wù)無法響應(yīng)据块,甚至嚴(yán)重的導(dǎo)致應(yīng)用崩潰。
Hystrix 具備服務(wù)降級后裸、服務(wù)熔斷瑰钮、依賴隔離 及服務(wù)監(jiān)控等強(qiáng)大功能。
使用機(jī)制
-
服務(wù)降級
Fallback相當(dāng)于是降級操作. 對于查詢操作, 我們可以實(shí)現(xiàn)一個fallback方法, 當(dāng)請求后端服務(wù)出現(xiàn)異常的時候, 可以使用fallback方法返回的值. fallback方法的返回值一般是設(shè)置的默認(rèn)值或者來自緩存.告知后面的請求服務(wù)不可用了微驶,不要再來了浪谴。
-
服務(wù)熔斷
當(dāng)服務(wù)者無法正常為消費(fèi)者提供服務(wù)時 ,如請求超時因苹、后臺服務(wù)無響應(yīng)苟耻、后臺服務(wù)異常等, 通過容錯機(jī)制直接返回統(tǒng)一處理結(jié)果扶檐,并對下次請求進(jìn)行同樣處理凶杖,直到后臺服務(wù)功能正常。
-
依賴隔離
(采用艙壁模式款筑,Docker就是艙壁模式的一種):在Hystrix中, 主要通過線程池來實(shí)現(xiàn)資源隔離. 通常在使用的時候我們會根據(jù)調(diào)用的遠(yuǎn)程服務(wù)劃分出多個線程池4.監(jiān)控(Hystrix Dashboard
一智蝠、項(xiàng)目案例
接著原來的項(xiàng)目user服務(wù)上添加配置
####### 1.1 application.java 配置
新增@EnableCircuitBreaker 腾么、@EnableHystrixDashboard注解
@EnableFeignClients
@EnableEurekaClient
@EnableCircuitBreaker //
@EnableDiscoveryClient
@EnableHystrixDashboard
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
......省略
}
1.2 ....yml配置
....
#開啟監(jiān)控端點(diǎn)
management:
endpoints:
web:
exposure:
include: hystrix.stream
#http://localhost:9001/mi-user/actuator/hystrix.stream 訪問.
...
二、使用Hystrixjiang 從而實(shí)現(xiàn)降級
2.1 在user服務(wù)創(chuàng)建一個接口實(shí)現(xiàn)hystrix
@FeignClient(value = "appoint"
, fallback = AppointClientHystrix.class
) 當(dāng)這個服務(wù)超時或者沒開啟的時候就會實(shí)現(xiàn)服務(wù)降級
@FeignClient(value = "appoint"
, fallback = AppointClientHystrix.class
)
public interface AppointClient {
// 調(diào)用 Appoint 服務(wù)
// 聲明接口式地址 @GetMapping("/mi-appoint/msg")
// 在到本服務(wù) Controller 調(diào)用 方法
// 訪問地址為本服務(wù)地址 localhost:9001/mi-appoint/controller地址
@GetMapping("/mi-appoint/msg")
public String appointMsg();
@GetMapping("/mi-appoint/appoint/uplist")
List<Appointment> upList();
}
2.2 接需要在appoint服務(wù)也創(chuàng)建一個給user服務(wù)接口調(diào)用
/**
* 獲取列表
* @return
*/
@GetMapping("uplist")
public List<Appointment> upList(){
return appointService.findUpAll();
}
2.3 測試不開啟appoint服務(wù)
此時示例的是返回為空
當(dāng)我們訪問地址的時候
2.4 測試開啟appoint服務(wù)
此時示例的是返回是有數(shù)據(jù)
三杈湾、Hystrix-dashboard 熔斷可視化界面
3.1 引入 pom 依賴包
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
3.2 創(chuàng)建一個HystrixController
@DefaultProperties(defaultFallback = "defaultFallback") 是使用本類的一個默認(rèn)失敗提示
@HystrixCommand 是配置一些降級配置
@RestController
@Slf4j
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixController {
//設(shè)置降級配置
// 超時時間3秒
@HystrixCommand(
commandProperties = {
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "1000"), //超時時間
// 斷熔器
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //設(shè)置熔斷
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), //請求數(shù)達(dá)到后才計(jì)算
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //休眠時間窗
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), //錯誤率
}
)
@GetMapping("getAppointInfoList")
public String getAppointByList(@RequestParam("number") Integer number){
if (number % 2 == 0) {
return "success";
}
log.info("mi-user:getAppointByList - > ");
RestTemplate restTemplate = new RestTemplate();
return restTemplate.getForObject(
"http://127.0.0.1:9002/mi-appoint/appoint/appointList",
String.class
);
}
@RequestMapping("test")
public String test(){
return "test";
}
private String fallback() {
return "太擁擠了, 請稍后再試~~";
}
private String defaultFallback() {
return "默認(rèn)提示:太擁擠了, 請稍后再試~~";
}
}
3.3 開啟Hystrix-dashboard
訪問地址:http://localhost:9001/mi-user/hystrix
輸入地址是:http://localhost:9001/mi-user/actuator/hystrix.stream
3.3 進(jìn)入監(jiān)控頁面
四解虱、測試使用監(jiān)控案例
通過兩個訪問地址通過監(jiān)控來觸發(fā)降級
http://localhost:9001/mi-user/getAppointInfoList?number=1
http://localhost:9001/mi-user/getAppointInfoList?number=1
4.1 測試過程
當(dāng)我們訪問第一個頁面的地址的時候,不斷刷新訪問
監(jiān)控的訪問接口圈圈子漆撞,隨著不斷刷新殴泰,會使百分比會達(dá)到我們配置觸發(fā)斷熔器設(shè)置的時候回實(shí)現(xiàn)降級服務(wù)
假設(shè)一開始我們訪問第二個地址是成功返回值的,而監(jiān)控里的值也沒有變化浮驳,此時是訪問成功的
然后我們一直刷新第一個頁面之后悍汛,監(jiān)控里的值會開始變化,再此訪問第二個頁面就會實(shí)現(xiàn)降級
然后當(dāng)我們在次多刷新的時候等待一會后至会,訪問第二個頁面离咐,就會開啟斷熔器,訪問成功
對于本次章節(jié)是對服務(wù)容錯和Hystrix簡單應(yīng)用
github項(xiàng)目地址:https://github.com/mi499938150/SpringCloud-Example.git