Hystrix是一個用于處理分布式系統(tǒng)延遲和容錯的開源庫,在分布式系統(tǒng)中,許多依賴會不可避免的調(diào)用失敗,比如超時、異常等。Hystrix能夠保證一個依賴出問題的情況下,不會導(dǎo)致整體服務(wù)失敗,避免級聯(lián)故障,以提高分布式系統(tǒng)的彈性。
斷路器本身是一種開關(guān)裝置,當(dāng)某個服務(wù)單元發(fā)送故障之后,通過斷路器的故障監(jiān)控(類似熔斷保險絲),向調(diào)用方返回一個符合預(yù)期的、可處理的備選響應(yīng)(FalBack),而不是長時間的等待或者拋出調(diào)用方無法處理的異常。這樣就保證了服務(wù)調(diào)用方線程不會被長時間、不必要的占用,從而避免了故障在分布式系統(tǒng)中的蔓延、乃至雪崩。
序 服務(wù)熔斷和服務(wù)降級的區(qū)別
主邏輯失敗而采用備用邏輯的過程,叫做服務(wù)降級。
而主邏輯由于多次失敗,會被暫時性忽略,不再嘗試調(diào)用,叫做服務(wù)熔斷。
注:服務(wù)降級和熔斷都是服務(wù)調(diào)用者端實現(xiàn)來完成的,與服務(wù)提供者無關(guān)!
1. 服務(wù)熔斷
1.1 什么叫做服務(wù)熔斷
熔斷服務(wù)時針對雪崩效應(yīng)的一種微服務(wù)鏈路保護機制。當(dāng)扇出鏈路的某個微服務(wù)不可用或者響應(yīng)時間太長,會進行服務(wù)的降級——進而熔斷微服務(wù)的調(diào)用,快速返回錯誤的響應(yīng)信息。當(dāng)檢測到該節(jié)點微服務(wù)調(diào)用響應(yīng)正常后恢復(fù)調(diào)用鏈路。在SpringCloud框架中熔斷機制是通過Hystrix實現(xiàn)。Hystrix會監(jiān)控微服務(wù)間調(diào)用的狀態(tài),當(dāng)失敗的調(diào)用到達一定的閾值(缺省是5s內(nèi)20次調(diào)用失敗就啟用熔斷機制)就會啟動熔斷機制。熔斷機制的注解時@HystrixCommand。
1.2 SpringCloud如何實現(xiàn)
服務(wù)降級和熔斷是客戶端實現(xiàn)的,與服務(wù)提供者無關(guān)!
1. maven依賴
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
2. 主啟動類上注解
@EnableCircuitBreaker注解開啟熔斷
3. 實現(xiàn)類上添加@HystrixCommand完成服務(wù)熔斷
當(dāng)服務(wù)調(diào)用異常時,會向調(diào)用方返回一個符合預(yù)期的、備選的調(diào)用方案。
@Override
@HystrixCommand(fallbackMethod = "backupCall")
public String call(String name) {
ResponseEntity resultResponseEntity = restTemplate.postForEntity(appServiceUrl + "hello?name=" + name, null, String.class);
if (resultResponseEntity != null && resultResponseEntity.getBody() != null) {
return name + " says: " + resultResponseEntity.getBody().toString();
}
return null;
}
public String backupCall(String name) {
return "Hi, I'm Hystix.";
}
若是我們將服務(wù)提供者服務(wù)停掉,服務(wù)調(diào)用者調(diào)用得到異常后,即主邏輯失敗,會重新調(diào)用備選邏輯。
1.3 降級的全局處理
若是每個方法上都使用@HystrixCommand注解,雖然可以實現(xiàn)服務(wù)降級以及熔斷,但是會造成代碼的過于臃腫。有什么方式可以實現(xiàn)降級的全局處理呢?
依靠于Feign,實現(xiàn)降級的全局處理。
1. 新增maven依賴
<dependencies>
<!--集成eureka client-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<!--集成web-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--Fegin依賴-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
</dependencies>
2. yml配置
server:
port: 82
#本機服務(wù)名
spring:
application:
name: microservicecloud-consumer-fegin-82
#注冊中心地址
eureka:
client:
service-url:
defaultZone: http://localhost:7000/eureka #單機版
register-with-eureka: false #不需要注冊
#開啟熔斷器
feign:
hystrix:
enabled: true
3. 主啟動類
@SpringBootApplication(scanBasePackages = {"com.galax"})
@EnableEurekaClient
@EnableDiscoveryClient //服務(wù)發(fā)現(xiàn)
@EnableFeignClients //開啟Fegin
public class Consumer_Feign_82 {
public static void main(String[] args)
{
SpringApplication.run(Consumer_Feign_82.class, args);
}
}
4. 在service中配置熔斷請求
//value是服務(wù)提供者的application.name
@FeignClient(value = "microservicecloud-provider",fallbackFactory = ClientFallbackFactory.class)
public interface XxxtService {
@RequestMapping("/XXX/getAxx")
String getAccount();
}
@Component //必須要使用Client
public class ClientFallbackFactory implements FallbackFactory<XxxService> {
@Override
public XxxService create(Throwable throwable) {
return new XxxService() {
@Override
public String getXxx() {
return "開啟服務(wù)降級~";
}
};
}
}