Hystrix熔斷應用
Hystrix,宣⾔“defend your app”是由Netflix開源的⼀個延遲和容錯庫,⽤於隔離訪問遠程系統、服務或者第三⽅庫,防⽌級聯失敗,從⽽提升系統的可⽤性與容錯性。Hystrix主要通過以下⼏點實現延遲和容錯。
- 包裹請求:使⽤HystrixCommand包裹對依賴的調⽤邏輯。 ⾃動投遞微服務⽅法(@HystrixCommand 添加Hystrix控制)
- 跳閘機制:當某服務的錯誤率超過⼀定的閾值時,Hystrix可以跳閘,停⽌請求該服務⼀段時間。
- 資源隔離:Hystrix爲每個依賴都維護了⼀個⼩型的線程池(艙壁模式)(或者信號量)。如果該線程池已滿, - 發往該依賴的請求就被⽴即拒絕,⽽不是排隊等待,從⽽加速失敗判定。
- 監控:Hystrix可以近乎實時地監控運⾏指標和配置的變化,例如成功、失敗、超時、以及被拒絕的請求等。
- 回退機制:當請求失敗、超時、被拒絕,或當斷路器打開時,執⾏回退邏輯。回退邏輯由開發⼈員⾃⾏提供,例如返回⼀個缺省值。
- ⾃我修復:斷路器打開⼀段時間後,會⾃動進⼊“半開”狀態
具體實現:
引入maven依賴座標
<!--熔斷器Hystrix-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
啓動類添加熔斷器開啓註解@EnableCircuitBreaker
@SpringBootApplication
@EnableDiscoveryClient // 開啓服務發現
@EnableCircuitBreaker // 開啓熔斷
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application .class, args);
}
/**
* 注⼊RestTemplate
* @return
*/
@Bean
// Ribbon負載均衡
@LoadBalanced
public RestTemplate getRestTemplate() {
return new RestTemplate();
}
}
定義服務降級處理⽅法,並在業務⽅法上使⽤@HystrixCommand的fallbackMethod屬性關聯到
服務降級處理⽅法
@RestController
@RequestMapping("/test")
public class TestController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/test/{id}")
@HystrixCommand(
// 線程池標識,要保持唯一,不唯一的話就共用了
threadPoolKey = "findResumeOpenStateTimeoutFallback",
// 線程池細節屬性配置
threadPoolProperties = {
@HystrixProperty(name="coreSize",value = "2"), // 線程數
@HystrixProperty(name="maxQueueSize",value="20") // 等待隊列長度
},
// commandProperties熔斷的一些細節屬性配置
commandProperties = {
// 每一個屬性都是一個HystrixProperty @HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds",value="2000")
// hystrix高級配置,定製工作過程細節
,
// 統計時間窗口定義
@HystrixProperty(name = "metrics.rollingStats.timeInMilliseconds",value = "8000"),
// 統計時間窗口內的最小請求數
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold",value = "2"),
// 統計時間窗口內的錯誤數量百分比閾值
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage",value = "50"),
// 自我修復時的活動窗口長度
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds",value = "3000")
},
fallbackMethod = "myFallBack" // 回退方法
)
public Integer test(@PathVariable Long id) {
// 使用ribbon不需要我們自己獲取服務實例然後選擇一個那麼去訪問了(自己的負載均衡)
String url = "http://server/test/" + id; // 指定服務名
Integer forObject = restTemplate.getForObject(url, Integer.class);
return forObject;
}
/*
定義回退方法,返回預設默認值
注意:該方法形參和返回值與原始方法保持一致
*/
public Integer myFallBack(Long id) {
return -123333; // 兜底數據
}
}
注意
降級(兜底)⽅法必須和被降級⽅法相同的⽅法簽名(相同參數列表、相同返回值)