工做中的微服務架構,某個服務一般會被多個服務調用或者多層調用完成需求,若是某個服務不可用,致使一個系統功能不可用或者服務直接沒用了的狀況,這種狀況稱爲雪崩效應html
有A服務調用B服務,B服務調用C服務,若是B服務調用C服務出了問題,那麼B服務會一直重試,等待會將資源耗盡,結果B服務也不可用,致使A服務調用B服務的時候,也出問題,這樣的話,ABC服務都癱了java
爲預防以上問題,在下面學習Spring Cloud Hystrix,防雪崩,容錯機制,基於NetFlix的Hystrixspring
Hystrix翻譯中文是豪豬的意思,沒見過也知道防護力很高的樣子,還有以前學習的Eureka翻譯中文的意思是找到了,就是後來詞化成發現docker
Hystrix 供分佈式系統使用,提供延遲和容錯功能,隔離遠程系統、訪問和第三方程序庫的訪問設計模式
Spring Cloud Hystrix服務器
①服務降級網絡
②服務熔斷架構
③依賴隔離app
④監控(Hystrix Dashboard)maven
根據以上特性功能開始學習
這個功能其實咱們平時也都見過,好比訪問某寶頁面搶購,某奇藝看東西會提示: 網絡開小差了,請稍後再試 等相似的提示
服務降級主導思想是區分業務,詳細體如今優先核心服務,非核心服務不可用或放低其可用度,就有一種棄車保帥的意思,舍小保大
假設一個電商系統,某天的交易有巨大的流量出現,擺好的服務器資源就這麼多,那麼優先保證商品、訂單、支付等服務的可用性,另外好比廣告、積分等就屬於非核心服務,那麼就能夠調度一下
細分到服務,好比商品服務,購買的時候,買家查詢頻繁度遠高於賣家查詢,那麼就能夠調度買家查詢爲核心服務,優先保證其可用性,另外買家查詢服務就屬於非核心服務,實際還須要根據業務場景調度
Hystrix的使用,經過@HystrixCommand註解,fallbackMethod回退函數實現降級邏輯
在以前的order服務和product服務進行學習,主要學習組件內容,按套路出牌
第一步maven加入Hystrix的依賴
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> </dependency>
注意: 若是後面@DefaultProperties註解沒法導入的話,在依賴上把版本號<version>加上
凡是遇到這樣的問題,大多數緣由是官方把這個包名改過了,爲了繼續使用原來已經使用過的組件依賴,要求加上version指定版本,才能夠
這邊spring-cloud-starter-hystrix的名字在spring cloud 2.0.3發佈的正式版中改爲了spring-cloud-starter-netflix-hystrix
因此引入依賴,改爲如下寫法就能夠了
<dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency>
第二步在啓動類上,將以前的註解替換成@SpringCloudApplication,
該註解包含@SpringBootApplication @EnableDiscoveryClient @EnableCircuitBreaker三個註解的效果
從這點你們就能夠明白怎麼整合註解功能的使用
@SpringCloudApplication @EnableFeignClients public class OrderApplication { public static void main(String[] args) { SpringApplication.run(OrderApplication.class, args); } }
第三步建立一個controller測試代碼
/** * 測試 使用hystrix */ @RestController @DefaultProperties(defaultFallback = "defaultFallback") public class HystrixController { /** * HystrixCommandProperties 參數對應查看 * 下面超時配置 */ @HystrixCommand( commandProperties = { @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "3000") } ) @GetMapping("/list") public String list() { RestTemplate restTemplate=new RestTemplate(); String s=restTemplate.postForObject("http://192.168.5.102:9001/product/list", Arrays.asList("1"),String.class); return s; } public String defaultFallback() { return "拼命加載中..."; } }
簡單的測試降級,請求發送會觸發defaultFallback的返回,相關配置信息也不用記,實在太長了,知道在哪裏就能夠了,若是不出現降級,能夠去url請求的終端服務作點小手腳,好比thread.sleep(xxx)
依賴隔離就想到以前學習的docker,也具備隔離特性,docker實現進程的隔離,使容器以前互不影響,回來Hystrix,他使用的是線程池隔離方式,Hystrix會爲每個hystrixcommand建立獨立的線程池,你就像上面測試的某一個依賴服務,並不會拖慢影響其餘的服務,Hystrix自動實現依賴隔離
微服務分佈式容錯機制必需要考慮,到目前知道的方式主要兩種,
①重試機制: 對應預期短暫的故障問題
②斷路器模式: 對應更長時間的故障問題,該模式是將受保護的服務封裝在一個能夠監控故障的斷路器對象中,當該服務的故障達到閥值,斷路器就會採起措施,跳閘斷路,斷路器對象被採起返回錯誤的方式告之
martin fowler發的一篇文章,關於CircuitBreaker(斷路器),
URL: https://martinfowler.com/bliki/CircuitBreaker.html
拿其中的執行狀態機制圖,作一個翻譯學習
以上解釋到斷路器設計模式---狀態機制,能夠看出有三種狀態closed、open、half open, 顧名思義,以熔斷路爲主角
closed: 熔斷器關閉狀態,調用失敗次數累計達到閥值,就會啓動熔斷機制
open/half open: 熔斷器打開狀態,此時對服務都直接返回錯誤,該處設計時鐘概念,到了點就會進入half open狀態,運行一些服務請求,若是請求是成功的,就認爲服務恢復了,關閉熔斷器closed,不然就繼續fail回到open狀態
代碼中註解配置寫法相似超時設置,主要參數以及說明 以下:
/** * HystrixCommandProperties 參數對應查看 * @return */ @HystrixCommand( commandProperties = { //超時設置 @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "2000"), //設置熔斷 @HystrixProperty(name = "circuitBreaker.enabled",value = "true"), //設置滾動窗口中,斷路器的最小請求數量 @HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "10"), //斷路器肯定是否須要打開統計請求和錯誤數據的時候,具備一個時間範圍即時間窗口,當斷路器打開, //對主邏輯進行熔斷以後,hystrix會啓動休眠時間窗,此時降級邏輯會稱爲主邏輯,當休眠時間窗到期,斷路 //器就進入half open狀態 //嘗試釋放請求到原主邏輯上,就想以前描述的,成功則斷路器閉合closed,失敗則繼續打開open,休眠時間 //窗將從新計時 //如下設置休眠時間窗爲10000毫秒 @HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), //設置斷路器打開的百分比條件, //好比此處設置爲60,在滾動窗口中發生了10次request,有7次發生了異常,超出設置值,則斷路器就進入 //open狀態,反之即closed @HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "60") } ) @GetMapping("/list") public String list() { ...... }
以上是粗略學習hystrix,因此配置都寫在了註解上面,下面轉化配置文件,以超時設置爲例,上面服務中的方法名字是list,下面設置一個默認超時設置和一個針對list方法的超時設置,在方法上須要加上@HystrixCommand註釋,該註解有一個commandKey參數,指定該方法的key使用斷路器,若是不設置默認是方法的名字,此處沒有其餘方法,圖方便就直接用名字
hystrix: command: default: execution: isolation: thread: timeoutInMilliseconds: 2500 list: execution: isolation: thread: timeoutInMilliseconds: 2800
關於Hystrix還有控制面板能夠觀察調控的更清晰,還有結合Hystrix+feign等方面的使用,繼續學習
-------------------------------------------------------------