在微服務當道的現下,系統架構中由業務拆分出多個系統之間,一般是經過遠程RPC調用進行通訊,好比系統1調用系統2的服務,系統2調用系統3,當系統3發生故障的時候就會致使,可能會致使前置的兩個系統發生崩潰,因此在系統架構中一般要保證系統的健壯性,好比使用降級策略,來保證由其餘系統提供的服務發生錯誤不可用的時候,服務的調用方能夠切換降級到正常的服務上使用。java
Netflix開源了Hystrix組件,實現了斷路器模式,Spring Cloud 對這一組組件進行了組合web
特色:隔離、降級、熔斷、緩存spring
隔離:包括線程池隔離和信號隔離,限制調用分佈式服務的資源使用,一個微服務出現問題不會影響其餘服務緩存
降級:超時降級、資源不足時降級、降級後能夠配合降級接口返回託底數據網絡
熔斷:當失敗率達到閥值自動觸發降級(好比網絡故障、服務異常),熔斷器觸發的快速失敗會進行快速恢復。架構
緩存:提供請求緩存、請求合併實現併發
正常狀況下,斷路器處於關閉狀態。若是在某段時間內,調用持續出錯或者超時,斷路器會被打開進入熔斷狀態,後續一段時間內的全部請求調用都會被拒絕。一段時間之後,保護器會嘗試進入半熔斷狀態,開放少許的請求進來,若是調用敗任然回到熔斷狀態,若是調用成功服務會到正常狀態,斷路狀態關閉。app
三種狀態的轉換:分佈式
closed -> open: 正常狀況熔斷器爲close狀態,當訪問的同一個服務或者接口次數超過必定的閥值,而且錯誤比例超過咱們預約的閥值時,就會打開熔斷機制,這個時候熔斷器的狀態就會從closed變成open狀態spring-boot
open -> half-open:當服務的熔斷器狀態爲open的時候,全部的服務調用方在請求該服務的時候都是在執行本地的降級方法,Hystrix提供了一個策略,從open狀態開始的時候記錄了一個時間窗口,當熔斷時間超過了這個時間時,就會把狀態變動爲half-open,這個時候遠程調用請求服務接口時,發起的是服務正常應該提供的調用,而再也不是降級策略,若是服務調用正常熔斷狀態會從half-open->closed轉變,熔斷關閉
若是請求仍是異常,就繼續從half-open->open轉變
若是沒有發生熔斷,還有一道門檻,Hystrix提供了一個信號量限流器,限制進入熔斷器最大併發數,能夠控制請求下游的併發量,若是超過這個閾值,會被降級處理,有效的保護下游服務不會被突發流量給攻擊。
將前兩節中的eureka服務與client啓動起來,在service-ribbon項目中添加Hystrix引用
<dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-ribbon</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-hystrix</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies>
啓動類中添加註解@EnableHystrix
@EnableDiscoveryClient @EnableEurekaClient @SpringBootApplication @EnableHystrix public class ServiceribbonApplication { public static void main(String[] args) { SpringApplication.run(ServiceribbonApplication.class, args); } @Bean @LoadBalanced RestTemplate restTemplate(){ return new RestTemplate(); } }
修改Controller加上@HystrixCommand註解。該註解對該方法建立了熔斷器的功能,並指定了fallbackMethod熔斷方法
@RestController @RequestMapping("hello") public class HelloControler { @Autowired HelloService helloService; @HystrixCommand(fallbackMethod = "hiError") @GetMapping(value = "/hi") public String hi(@RequestParam String name) { String a=helloService.hiService( name ); return a; } public String hiError(String name){ return "調用服務下線"; } }
run起來,請求hi接口的時候,調用服務不通或者異常的時候將會執行指定的熔斷方法。
正常啓動eureka的client後,運行service-ribbon能夠正常調用服務並返回字符串
hi aa ,i am from port:1002
手動停掉client後,再次請求
調用服務下線