SpringCloud中的Hystrix保護(hù)機(jī)制詳解
Hystrix簡介
Hystrix,英文意思是豪豬,全身是刺,看起來就不好惹,是一種保護(hù)機(jī)制。
Hystrix也是Netflix公司的一款組件。
那么Hystix的作用是什么呢?具體要保護(hù)什么呢?
Hystix是Netflix開源的一個延遲和容錯庫,用于隔離訪問遠(yuǎn)程服務(wù)、第三方庫,防止出現(xiàn)級聯(lián)失敗。
雪崩問題
就好比,一個汽車生產(chǎn)線,生產(chǎn)不同的汽車,需要使用不同的零件,如果某個零件因?yàn)榉N種原因無法使用,那么就會造成整臺車無法裝配,陷入等待零件的狀態(tài),直到零件到位,才能繼續(xù)組裝。
此時如果有很多個車型都需要這個零件,那么整個工廠都將陷入等待的狀態(tài),導(dǎo)致所有生產(chǎn)都陷入癱瘓。
一個零件的波及范圍不斷擴(kuò)大。
Hystix解決雪崩問題的手段有兩個:
- 線程隔離
- 服務(wù)熔斷
線程隔離,服務(wù)降級
Hystrix為每個依賴服務(wù)調(diào)用分配一個小的線程池,如果線程池已滿調(diào)用將被立即拒絕,默認(rèn)不采用排隊.加速失敗判定時間。
用戶的請求將不再直接訪問服務(wù),而是通過線程池中的空閑線程來訪問服務(wù),如果線程池已滿,或者請求超時,則會進(jìn)行降級處理,什么是服務(wù)降級?
服務(wù)降級:優(yōu)先保證核心服務(wù),而非核心服務(wù)不可用或弱可用。
用戶的請求故障時,不會被阻塞,更不會無休止的等待或者看到系統(tǒng)崩潰,至少可以看到一個執(zhí)行結(jié)果(例如返回友好的提示信息) 。
服務(wù)降級雖然會導(dǎo)致請求失敗,但是不會導(dǎo)致阻塞,而且最多會影響這個依賴服務(wù)對應(yīng)的線程池中的資源,對其它服務(wù)沒有響應(yīng)。
觸發(fā)Hystix服務(wù)降級的情況:
線程池已滿 請求超時
使用
使用hystrix步驟:
1.引入hystrix依賴
2.在啟動類上加@EnableCircuitBreaker注解開啟隔離和熔斷
3.配置文件 配置超時時長 不配置 也有默認(rèn)值
引入依賴
在消費(fèi)方引入依賴
<!--使用線程隔離和服務(wù)降級引入 hystrix依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
</dependencies>開啟隔離
在消費(fèi)者的啟動類上
//@EnableDiscoveryClient//開啟負(fù)載均衡
//@EnableCircuitBreaker//開啟服務(wù)隔離和熔斷
//@SpringBootApplication
@SpringCloudApplication//springCloud注解 包含了以上三個注解配置這個不需要配置以上三個注解
public class UserConsumerDemoApplication {
@Bean
@LoadBalanced//負(fù)載均衡的另一種使用方法 內(nèi)置一個攔截器 攔截所有restTemplate請求
public RestTemplate restTemplate() {
// 這次我們使用了OkHttp客戶端,只需要注入工廠即可
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(UserConsumerDemoApplication.class, args);
}
}@springCloud注解源碼
* @SpringBootApplication
* @EnableDiscoveryClient
* @EnableCircuitBreaker
* public @interface SpringCloudApplication {
* }編寫降級邏輯
我們改造iconsumer,當(dāng)目標(biāo)服務(wù)的調(diào)用出現(xiàn)故障,我們希望快速失敗,給用戶一個友好提示。因此需要提前編寫好失敗時的降級處理邏輯,要使用HystixCommond來完成
消費(fèi)者的控制層中
@RestController
@RequestMapping("/consumer")
@DefaultProperties(defaultFallback = "defaultFallBack")//默認(rèn)屬性 寫在類上 類中所有方法通用屬性
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@GetMapping("{id}")
@HystrixCommand(fallbackMethod = "queryByIdFallBack")//開啟線程隔離和降級 fallbackMethod指定失敗方法
//類上配置了 方法上直接配置@HystrixCommand注解就行
@HystrixCommand(commandProperties = { //配置單個方法的超時時間 配置整體的超時時間需要在配置文件中配置
//設(shè)置超時時長為兩秒
@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
})
public String queryById(@PathVariable("id") Long id){
String url="http://user-service/user/"+id;
String user = restTemplate.getForObject(url, String.class);
return user;
}
//失敗方法和成功方法 參數(shù) 返回值必須一樣 方法名不做限制
public String queryByIdFallBack(Long id){
return "服務(wù)正忙,稍后重試";
}
//在方法上配置寫參數(shù) 在類上配置通用的 不能寫參數(shù)
public String defaultFallBack(){
return "服務(wù)正忙,稍后重試";
}改造服務(wù)提供者
改造userservice的控制層 觸發(fā)降級
@GetMapping("{id}")
public User queryUserById(@PathVariable("id") Long id) {
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return this.userService.queryUserById(id);
}
要注意,因?yàn)槿蹟嗟慕导夁壿嫹椒ū仨毟_壿嫹椒ūWC:相同的參數(shù)列表和返回值聲明。失敗邏輯中返回User對象沒有太大意義,一般會返回友好提示。所以我們把queryById的方法改造為返回String,反正也是Json數(shù)據(jù)。這樣失敗邏輯中返回一個錯誤說明,會比較方便。
設(shè)置超時
在之前的案例中,請求在超過1秒后都會返回錯誤信息,這是因?yàn)镠ystix的默認(rèn)超時時長為1,我們可以通過配置修改這個值:
yaml配置
消費(fèi)者yaml中加入
hystrix:
command:
default:
execution:
isolation:
thread:
timeoutInMilliseconds: 6000 # 設(shè)置hystrix的超時時間為6000ms
服務(wù)熔斷
熔斷器,也叫斷路器,其英文單詞為:Circuit Breaker 。
熔斷狀態(tài)機(jī)3個狀態(tài):
Closed:關(guān)閉狀態(tài),所有請求都正常訪問。
Open:打開狀態(tài),所有請求都會被降級。Hystix會對請求情況計數(shù),當(dāng)一定時間內(nèi)失敗請求百分比達(dá)到閾值,則觸發(fā)熔斷,斷路器會完全打開。默認(rèn)失敗比例的閾值是50%,請求次數(shù)最少不低于20次。
Half Open:半開狀態(tài),open狀態(tài)不是永久的,打開后會進(jìn)入休眠時間(默認(rèn)是5S)。隨后斷路器會自動進(jìn)入半開狀態(tài)。此時會釋放部分請求通過,若這些請求都是健康的,則會完全關(guān)閉斷路器,否則繼續(xù)保持打開,再次進(jìn)行休眠計時
為了控制請求的成功或失敗,我們在consumer的控制層中加入一段邏輯:
public String queryById(@PathVariable("id") Long id){
//因?yàn)楹茈y模擬熔斷現(xiàn)象我們只能手動控制 如果傳入的是偶數(shù)就熔斷 如果是技術(shù)就恢復(fù)正常
if(id%2==0){
throw new RuntimeException("");
}
String url="http://user-service/user/"+id;
String user = restTemplate.getForObject(url, String.class);
return user;
}@GetMapping("{id}")
// @HystrixCommand(fallbackMethod = "queryByIdFallBack")//開啟線程隔離和降級 fallbackMethod指定失敗方法
//類上配置了 方法上直接配置@HystrixCommand注解就行
// @HystrixCommand(commandProperties = { //配置單個方法的超時時間 配置整體的超時時間需要在配置文件中配置
// //設(shè)置超時時長為兩秒
// @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",value = "2000")
// })
@HystrixCommand(
commandProperties = { //配置單個方法的超時時間 配置整體的超時時間需要在配置文件中配置
//設(shè)置熔斷器統(tǒng)計次數(shù)為10次
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"),
//設(shè)置休眠時間窗為10秒
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "10000"),
//設(shè)置錯誤百分比 為百分之六十 十次失敗六次熔斷
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60")
})requestVolumeThreshold:觸發(fā)熔斷的最小請求次數(shù),默認(rèn)20
errorThresholdPercentage:觸發(fā)熔斷的失敗請求最小占比,默認(rèn)50%
sleepWindowInMilliseconds:休眠時長,默認(rèn)是5000毫秒
也可以在yaml配置文件中設(shè)置全局的時長
hystrix:
command: #指令
default: #全局的
execution:
isolation:
thread:
timeoutInMilliseconds: 3000 #配置全局超時時長為3秒到此這篇關(guān)于SpringCloud中的Hystrix保護(hù)機(jī)制詳解的文章就介紹到這了,更多相關(guān)SpringCloud的Hystrix內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Apache?Commons?Config管理配置文件核心功能使用
這篇文章主要為大家介紹了Apache?Commons?Config管理和使用配置文件核心深入探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
java利用jieba進(jìn)行分詞的實(shí)現(xiàn)
本文主要介紹了在Java中使用jieba-analysis庫進(jìn)行分詞,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-03-03
SpringBoot使用Logback進(jìn)行日志記錄的代碼示例
在開發(fā)Web應(yīng)用程序時,日志記錄是非常重要的一部分,在SpringBoot中,我們可以使用Logback進(jìn)行日志記錄,Logback是一款高性能、靈活的日志框架,它可以滿足各種不同的日志需求,在本文中,我們介紹了如何在SpringBoot中使用Logback進(jìn)行日志記錄2023-06-06
Java實(shí)現(xiàn)從字符串中找出數(shù)字字符串的方法小結(jié)
這篇文章主要介紹了Java實(shí)現(xiàn)從字符串中找出數(shù)字字符串的方法,結(jié)合實(shí)例形式總結(jié)分析了Java查找數(shù)字字符串的常用技巧,需要的朋友可以參考下2016-03-03
Java微信二次開發(fā)(二) Java微信文本消息接口請求與發(fā)送
這篇文章主要為大家詳細(xì)介紹了Java微信二次開發(fā)第二篇,Java微信文本消息接口請求與發(fā)送功能,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-04-04
springboot如何獲取yaml/yml(或properties)配置文件信息
在SpringBoot項目中,讀取配置文件信息是常見需求,可以通過@Autowired注入Environment類,使用@Value注解直接注入配置信息,或定義工具類結(jié)合ApplicationRunner進(jìn)行高級配置信息獲取,特別提到2024-11-11

