Hystrix 服務熔斷
- 容錯機制:微服務和分布式裡面,容錯是必須要考慮的!通常的做法有兩種
- 一種是重試機制,對于預期的短暫故障問題,可以重試解決;
- 二是使用斷路器模式,即将受保護的服務封裝到一個可以監控故障的斷路器裡面,當故障達到一定的值,斷路器将會跳閘,斷路器對象傳回錯誤!
斷路器狀态機: 1.closed,熔斷器關閉狀态,調用失敗次數累計到一定門檻值/比例,啟動熔斷機制,進入打開狀态 2.open,熔斷器打開狀态,對服務直接傳回錯誤,直接服務降級 3.half open,熔斷器打開狀态達到了一定的時間,會進入半熔斷狀态,允許定量的服務請求主邏輯。如果都調用成功,或者一定比例成功,則認為恢複,關閉熔斷器;否則,熔斷器回到打開狀态
斷路器模式設計狀态機(三種狀态)
- Closed(熔斷器的關閉狀态):熔斷器關閉狀态,調用失敗次數累計到一定門檻值/比例,啟動熔斷機制,進入打開狀态
- Open(熔斷器打開狀态):熔斷器打開狀态,對服務直接傳回錯誤,直接服務降級
- Half Open(熔斷器半熔斷狀态):熔斷器打開狀态達到了一定的時間,會進入半熔斷狀态,允許定量的服務請求主邏輯。如果都調用成功,或者一定比例成功,則認為恢複,關閉熔斷器;否則,熔斷器回到打開狀态
- sleepWindowInMilliseconds:休眠時間視窗
- requestVolumeThreshold:最小的請求數
- errorThresholdPercentage:服務錯誤百分比(比如百分之70,就是10個請求,有7個錯誤)
Product 微服務項目
@PostMapping("/listForOrder")
public List<ProductInfoOutput> listForOrder(@RequestBody List<String> productIdList) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return productService.findList(productIdList);
}
Order 微服務項目
package com.imooc.order.controller;
import com.netflix.hystrix.contrib.javanica.annotation.DefaultProperties;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import java.util.Arrays;
@RestController
@DefaultProperties(defaultFallback = "defaultFallback")
public class HystrixController {
@HystrixCommand(commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled", value = "true"), //設定熔斷
@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "10"), // 請求數達到後才計算
@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "10000"), // 熔斷時間
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage", value = "60"), // 錯誤率
})
@GetMapping("/getProductInfoList")
public String getProductInfoList(@RequestParam("number") Integer number) {
if (number % 2 == 0) {
return "success";
}
RestTemplate restTemplate = new RestTemplate();
return restTemplate.postForObject("http://127.0.0.1:8005/product/listForOrder",
Arrays.asList("157875196366160022"),
String.class);
}
private String defaultFallback() {
return "預設提示:太擁擠了, 請稍後再試~~";
}
}
- 此時預設 1s(為了達到降級效果),這裡模拟了一個奇數偶數判斷是為了模拟熔斷的場景。