Hystrix是一個用於處理分佈式系統的延遲和容錯的開源庫。Hystrix主要用於處理分佈式系統中複雜多變的服務依賴調用失敗、超時、異常等狀況,保證一個服務依賴出問題的狀況下,提供一個服務預期的、可處理的備選響應(FallBack),避免微服務總體級聯故障,以提升分佈式系統的彈性。git
Hystrix旨在執行如下操做:github
Hystrix在分佈式項目中主要用於處理:spring
首先對應服務熔斷咱們要理解「服務雪崩」的概念,服務雪崩是多個微服務之間調用的時候,假設微服務A調用微服務B和微服務C,微服務B和微服務C又調用其它的微服務,這就是所謂的「扇出」。若是扇出的鏈路上某個微服務的調用響應時間過長或者不可用,對微服務A的調用就會佔用愈來愈多的系統資源,進而引發系統崩潰,就是所謂的「雪崩」。數據庫
熔斷機制是應對雪崩效應的一種微服務鏈路保護機制。api
當扇出鏈路的某個微服務不可用或者響應時間太長時,就會經過熔斷該節點微服務的調用,快速返回錯誤的響應信息。當檢測到該節點微服務調用響應正常後恢復調用鏈路。網絡
在SpringCloud框架裏熔斷機制經過Hystrix實現。Hystrix會監控微服務間調用的情況,當失敗的調用到必定閾值,缺省是5秒內20次調用失敗就會啓動熔斷機制。熔斷機制的註解是@HystrixCommand。mybatis
這裏咱們仍是基於咱們以前博客的微服務項目springcloud-provider-dept-8001 服務端 複製一份做爲hystrix的微服務項目。app
①添加hystrix pom.xml依賴包:框架
<!--引入hystrix--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>1.4.6.RELEASE</version> </dependency>
②修改application.yml配置,修改了實例名稱:分佈式
server:
port: 8001
##省略了數據庫鏈接信息與mybatis配置
#eureka的配置,肯定客戶端服務註冊到eureka服務列表內
eureka:
client:
service-url:
#集羣配置
defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/
#defaultZone: http://localhost:7001/eureka/
instance:
instance-id: springcloud-provider-dept-hystrix-8001 #修改eureka上默認的服務描述信息
prefer-ip-address: true #訪問路徑能夠顯示ip地址
③基於Controller層的調用方法經過id獲取Dept用戶來作異常斷定:
@RestController @RequestMapping("/dept") public class DeptController { @Autowired private DeptService service; @GetMapping("/queryById/{id}") /*@HystrixCommand表示一旦調用服務方法失敗並拋出了異常信息以後, 會自動調用@HystrixCommand標註好的fallbackMethod中指定名稱的方法*/ @HystrixCommand(fallbackMethod = "processHystrixGet") public Dept queryById(@PathVariable("id") Long id){ Dept dept = service.queryById(id); //模擬當查詢不到id或者id信息異常時返回錯誤異常的提示 if(null == dept){ throw new RuntimeException("id=>" + id + "不存在該用戶,或者用戶信息沒法找到!"); } return dept; }; //熔斷備選方法:異常回調信息顯示 public Dept processHystrixGet(@PathVariable("id") Long id){ return new Dept() .setDeptno(id) .setDname("id=>" + id + "沒有對應的信息,null--@Hystrix") .setDbSource("no this database in MySQL"); } }
④在主啓動類上添加對hystrix的熔斷機制的支持:
@SpringBootApplication @EnableEurekaClient //在服務啓動後自動註冊到eureka中 @EnableDiscoveryClient //服務發現 @EnableCircuitBreaker //啓用對hystrix的熔斷機制的支持 public class DeptProvider8001_Hystrix_App { public static void main(String[] args) { SpringApplication.run(DeptProvider8001_Hystrix_App.class, args); } }
⑤啓動Eureka客戶端、Hystrix服務端進行訪問驗證:
訪問正常存在的服務id,能返回正常數據:
訪問異常不存在的id時,返回fallback方法中的信息:
能夠看出,當執行調用某個微服務發生異常時,Hystrix能經過自定義的fallbackMethod作異常的錯誤返回,快速進行異常熔斷機制。
服務熔斷是在服務運行的狀況下,對於服務內部執行錯誤的異常狀況的一種處理方式。
服務降級是從網站總體的負載考慮,當某個服務在某一時間內承受大量的服務請求,而須要極大的資源消耗,須要關閉當前系統的某些服務,作資源的擴充。犧牲單個服務的運行,當再次訪問這單個服務的時候,經過服務降級處理,返回給客戶設定的默認缺省值。
至關於棄軍保帥,維護的是整個系統的可用性。
服務降級這裏從客戶端進行實現。
(1)首先在springcloud-api中定義一個降級以後的回調函數類,實現FalllbackFactory接口,接口中實現了對應請求信息的異常處理方法:
@Component //注意不要忘記添加,須要把類加載進Spring容器中才能獲取到 public class DeptClientServiceFallbackFactory implements FallbackFactory<DeptClientService> { @Override public DeptClientService create(Throwable throwable) { return new DeptClientService() { @Override public boolean addDept(Dept dept) { return false; } @Override public Dept queryById(Long id) { return new Dept().setDeptno(id).setDname("該ID:" + id + "沒有對應的信息,Consumer客戶端提供的降級信息,此刻服務provider已經關閉"). setDbSource("no this database in MySQL"); } @Override public List<Dept> queryAll() { return null; } }; } }
(2)對應api接口中使用fallabckFatory去指定調用的是哪一個class實現類:
//value中對應服務提供方的名字 //服務降級:表示DeptClientService當前接口中任何一個方法出了問題:都去找DeptClientServiceFallbackFactory回調處理 @FeignClient(value = "SPRINGCLOUD-PROVIDER-DEPT", fallbackFactory = DeptClientServiceFallbackFactory.class) @Component //注入到容器中 public interface DeptClientService { /** * 接口中的三個方法對應服務提供者的三個方法 * 這裏面的接口對應服務提供者的controller接口,名稱必須一致,而後接口的Mapping映射url必須一致 * @param dept * @return */ @PostMapping("/dept/add") public boolean addDept(Dept dept); @GetMapping("/dept/queryById/{id}") public Dept queryById(@PathVariable("id") Long id); @GetMapping("/dept/queryAll") public List<Dept> queryAll(); }
(3)基於FeignClinet調用,則須要修改服務提供者中application.yml,開啓feign中對hystrix的支持:
#開啓降級feign.hystrix支持 feign: hystrix: enabled: true
(4)測試驗證:
步驟:啓動三個Eureka註冊中心700一、700二、7003,啓動provider-dept-8001做爲服務提供者、啓動consumer-dept-feign服務消費者:
能夠看到服務提供者已經註冊進去並正常運行:
經過客戶端consumer-feign的81端口也能訪問到對應的id數據:
(5)模擬服務熔斷異常:
關閉服務提供方provider-dept-8001,同時訪問81端口的數據請求:
能夠看到此時調用到了咱們編寫的fallbackFactory中的回調方法顯示降級信息。
因此即便服務關閉以後,Hystrix的服務熔斷機制也能避免大量重複無效訪問帶來的服務異常,能較好的提供客戶體驗。
本節涉及實例及相關代碼已上傳至github:
https://github.com/devyf/SpringCloud_Study/tree/main/springcloud_hello