一、服務熔斷
Hystrix是一個用於處理分布式系統的延遲和容錯的開源庫,在分布式系統中,許多依賴不可避免的會調用失敗,超時、異常等,Hystrix能夠保證在一個依賴出問題的情況下,不會導致整體服務失敗,避免級聯故障,提高分布式系統的彈性
熔斷機制是應對雪崩效應的一種微服務鏈路保戶機制,當扇出鏈路的某個微服務不可用或者響應時間太長時,會進行服務的降級,進而熔斷該節點微服務的調用,快速返回錯誤的相應信息。當檢測當該節點微服務調用響應正常后恢復調用鏈路,熔斷機制的注解是@HystrixCommand
“熔斷器”本身是一種開關裝置,當某個服務單元發生故障之后,通過斷路器的故障監控,,某個異常條件被觸發,直接熔斷整個服務。,向調用方法返回一個符合預期的、可處理的備選響應(FallBack),而不是長時間的等待或者拋出吊牌用方法無法處理的異常,就保證了服務調用方的線程不會被長時間占用,避免故障在分布式系統中蔓延,乃至雪崩
使用步驟:
1、導入maven依賴
<!-- 服務熔斷的依賴 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-hystrix</artifactId> <version>1.2.3.RELEASE</version> </dependency>
2、在調用方法@HystrixCommand注解
注意:
當查詢數據庫時,User是存在的,則正常返回,當不存在時User為null,我自定義了一個異常
此時該方法出現異常,就會通過 @HystrixCommand(fallbackMethod ="hystrix_GET" ),找到下面的備選響應
//正常的功能方法 @GetMapping("/product/findone/{id}") @HystrixCommand(fallbackMethod ="hystrix_GET" ) //去找備選響應,進行服務降級 public User findById(@PathVariable("id") Integer id) { User user = userService.findById(id); if (null == user){ throw new RuntimeException("該"+id+"沒有對應信息"); } return user; } //備選響應,服務降級 public User hystrix_GET(@PathVariable("id") Integer id){ return new User(id,"該ID:"+id+"沒有對應的數據","Hystrix服務降級"); }
3、啟動類上加@EnableCircuitBreaker注解,開啟服務熔斷機制
@SpringBootApplication
@MapperScan("com.ghh.mapper")
@EnableEurekaClient
@EnableCircuitBreaker //開啟服務熔斷機制
public class ProductStart_8003 {
public static void main(String[] args) {
SpringApplication.run(ProductStart_8003.class,args);
}
}
4、運行頁面
5,向調用方返回一個符合預期的、可處理的備選響應的
此時:spring強調業務邏輯,處理異常信息,要分離,上面的方法會發生方法膨脹,耦合太嚴重,最終業務主邏輯和
熔斷的處理方式,在接口綁定,實現與主邏輯解耦
二、服務降級
服務降級處理是在客戶端實現完成的,與服務端沒有關系
整體資源快不夠了,忍痛將某些服務單元先關掉,關閉后還要返回一些可處理的備選方法,待渡過難關,再開啟回來,
使用步驟:
1、在api層創建一個一個降級服務,並實現FallbackFactory接口,且泛型為Feign的調用接口
切記,必須在類上方加上@Component注解,
@Component public class UserClientService implements FallbackFactory<UserService> { //Feign調用的接口 @Override public UserService create(Throwable throwable) { //構建匿名 return new UserService() { @Override public User findById(Integer id) { return new User(id,"該ID:"+id+"沒有對應的數據","Hystrix此服務以關閉"); } @Override public List<User> findAll() { return null; } }; } }
2、在api的接口中(此處我的分布式項目中使用的是Feign的調用方法)
@FeignClient(value = "MICROSERVICE-PRODUCT",fallbackFactory = UserClientService.class) //指明服務關閉后,會返回方法的類的字節碼 public interface UserService { @GetMapping("/product/findone/{id}") public User findById(@PathVariable("id") Integer id); @GetMapping("/product/list") public List<User> findAll(); }
3、在消費者模塊的配置文件yml中
feign: #開啟服務熔斷服務降級
hystrix:
enabled: true
4、測試
開啟eureka的集群,提供者,Feign的消費者,然后進行測試
當我們的整體資源不快夠用,需要關閉提供該服務,又不想整體資源因依賴這個服務而發生級聯效應,我們使用了上面的技術進行了服務降級處理,
當我們關閉此服務后
總結:
分布式項目中,有數十個依賴關系,每個依賴關系在某些時候不可避免地失敗,
服務雪崩:當A調用微服務B,B調C,和其他微服務,這是扇出,當扇出鏈路上某個微服務調用響應時間過長或者不可用,對微服務的A的調用就會占用越來越多的系統資源,導致系統崩潰,所謂的雪崩效應
服務熔斷:一般是某個服務異常引起的,相當於“保險絲”,當某個異常條件被觸發,直接熔斷整個服務,不是等到此服務超時
服務降級:降級一般是從整體負荷考慮,當某個服務熔斷之后,服務器將不再被調用,客戶端可自己准備一個本地的fallback回調,返回一個缺省值,雖然服務水平下降,當能用,比直接掛掉要強
springcloud是spring,采用AOP的思想,異常處理信息,我們某個服務的功能是每個方法,我們還可以使用AOP直接在api層通過接口設置服務降級