一、初識Hystrix
Hystrix [hɪst'rɪks],中文含義是豪豬,因其背上長滿棘刺,從而擁有了自我保護的能力。本文所說的Hystrix是Netflix開源的一款容錯框架,同樣具有自我保護能力。為了實現容錯和自我保護,下面我們看看Hystrix如何設計和實現的。
Hystrix設計目標:
- 對來自依賴的延遲和故障進行防護和控制——這些依賴通常都是通過網絡訪問的
- 阻止故障的連鎖反應
- 快速失敗並迅速恢復
- 回退並優雅降級
- 提供近實時的監控與告警
Hystrix⽤於隔離訪問遠程系統、服務或者第三⽅庫,防⽌級聯失敗,從⽽提升系統的可⽤性與容錯性。Hystrix主要通過以下⼏點實現這些設計目標,主要包括延遲和容錯。
- 包裹請求:使⽤HystrixCommand或HystrixObservableCommand包裹對依賴的調⽤邏輯(切面增強的原理)
- 跳閘機制:當某服務的錯誤率超過⼀定的閾值時,Hystrix可以跳閘,停⽌請求該服務⼀段時間
- 資源隔離:Hystrix為每個依賴都維護了⼀個⼩型的線程池(艙壁模式)(或者信號量)。如果該線程池已滿, 發往該依賴的請求就被⽴即拒絕,⽽不是排隊等待,從⽽加速失敗判定
- 監控:Hystrix可以近乎實時地監控運⾏指標和配置的變化,例如成功、失敗、超時、以及被拒絕的請求等
- 回退機制:當請求失敗、超時、被拒絕,或當斷路器打開時,執⾏回退邏輯。回退邏輯由開發⼈員⾃⾏提供,例如返回⼀個缺省值
- ⾃我修復:斷路器打開⼀段時間后,會⾃動進⼊“半開”狀態
二、應用
1、引入pom依賴
由於父項目中已經引入了SpringCloud依賴的版本管理,所以我這里只引入沒有指定version屬性,如果你的項目中沒有版本管理需要單獨引入version屬性.
<!--熔斷器Hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> <!--<version> 2.0.2.RELEASE</version>--> </dependency>
2、引入pom依賴之后需要在啟動類上開啟熔斷器
注解介紹如果僅僅需要是一個熔斷使用@EnableCircuitBreaker即可
@EnableDiscoveryClient 注解聲明啟動Ribbon負載
@EnableHystrix 標識使用Hystrix,在SpringBoot2.x版本后也可以省略掉
@EnableCircuitBreaker 標識開啟熔斷器
@SpringCloudApplication 注解等同與同屬引入@SpringBootAppliction + @EnableDiscoveryClient + @EnableCircuitBreaker注解
/** * @author niunafei * @function * @email niunafei0315@163.com * @date 2020/9/2 6:11 PM * <p> * 注解簡化寫法 * @SpringCloudApplication = @SpringBootApplication + @EnableDiscoveryClient + @EnableCircuitBreaker */ @SpringBootApplication @EnableDiscoveryClient @EnableHystrix @EnableCircuitBreaker //@SpringCloudApplication public class AutodeliverApplication { public static void main(String[] args) { SpringApplication.run(AutodeliverApplication.class, args); } /** * 注⼊RestTemplate * LoadBalanced開啟ribbon * * @return */ @Bean @LoadBalanced public RestTemplate getRestTemplate() { return new RestTemplate(); } }
3、調取客戶端進行配置使用
多個參數說明,具體概念參考-->這里
代碼硬編碼如下,應用於單個接口,這里存在跳閘與自我修復機制、線程池(艙壁模式)、服務降級。
// 使⽤@HystrixCommand注解進⾏熔斷控制 @HystrixCommand( // 線程池標識,倉壁模式的應用,每一個標識獨立線程池,要保持標識唯⼀,不唯⼀的話就共⽤了 threadPoolKey = "findResumeOpenState", // 線程池細節屬性配置 threadPoolProperties = { @HystrixProperty(name = "coreSize", value = "1"), // 線程數,默認10個線程 @HystrixProperty(name = "maxQueueSize", value = "20") // 等待隊列⻓度 }, // commandProperties熔斷的⼀些細節屬性配置 commandProperties = { // 每⼀個屬性都是⼀個HystrixProperty,HystrixCommandProperties可以獲取配置信息 //服務降級,設置超時時間2秒 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"), //以下配置是熔斷跳閘與自我修復:8秒鍾內,請求次數達到2個,並且失敗率在50%以上,就跳閘,跳閘后活動窗⼝設置為3s,即三秒后進行重試 //統計時間窗口定義 @HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "8000"), //最小請求數量 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "2"), //統計時間框口內的異常百分比 @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"), //自我修復活動窗口時長 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "3000") }, //異常返回方法,也是服務降級,方法的入參和返回值與該方法一致,在類上@DefaltProperties(defaultFallback="fallback")注解是為全類指定降級回調方法 fallbackMethod = "fallback" ) @GetMapping("/checkState/{userId}") public String findResumeOpenState(@PathVariable Long userId) { //發起調用 Long start = System.currentTimeMillis(); Integer forObject = restTemplate.getForObject("http://city-service-resume/resume/openstate/" + userId, Integer.class); System.out.println("======>>>調⽤微服務,獲取到⽤戶" + userId + "的默認 當前狀態為:" + forObject); return forObject + " ,響應時間" + (System.currentTimeMillis() - start); } /** * 降級返回值 * * @param userId * @return */ public String fallback(Long userId) { return -1 + " ,響應時間" + (System.currentTimeMillis() - System.currentTimeMillis()); }
全局配置如下(僅僅適用於commandProperties內的屬性配置):改配置應用於全局HystrixCommand注解
# 配置熔斷策略:
hystrix:
command:
default:
circuitBreaker:
# 強制打開熔斷器,如果該屬性設置為true,強制斷路器進⼊打開狀態,將會拒絕所有的請求。 默認false關閉的
forceOpen: false
# 觸發熔斷錯誤⽐例閾值,默認值50%
errorThresholdPercentage: 50
# 熔斷后休眠時⻓,默認值5秒
sleepWindowInMilliseconds: 3000
# 熔斷觸發最⼩請求次數,默認值是20
requestVolumeThreshold: 2
execution:
isolation:
thread:
# 熔斷超時設置,默認為1秒
timeoutInMilliseconds: 2000
提示:簡單測試熔斷器的狀態(是否被熔斷),方式通過SpringBoot的健康檢查接口即可。需要:
第一步配置開啟健康檢查(如下)
第二步然后訪問http://ip:端口/actuator/health接口
第三步查看返回json的hystrix屬性。
# springboot中暴露健康檢查等斷點接⼝
management:
endpoints:
web:
exposure:
include: "*"
# 暴露健康接⼝的細節
endpoint:
health:
show-details: always
三、監控
上面鏈接監控儀表盤需要注意的點:
1、正常配置springCloud的配置文件,包括應用名稱與Eureka的注冊中心等配置
2、上面使用的spring原生xml配置方式,在springboot中被監控的應用添加以下Bean對象配置即可
@Bean public ServletRegistrationBean getServlet(){ HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet(); ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet); //啟動狀態 registrationBean.setLoadOnStartup(1); //mvc訪問路徑 registrationBean.addUrlMappings("/actuator/hystrix.stream"); //bean名稱 registrationBean.setName("HystrixMetricsStreamServlet"); return registrationBean; }