天天看點

SpringCloud—Hystrix入門學習1 背景2 Hystrix簡介3 Hystrix使用

1 背景

雪崩效應:微服務架構的應用系統通常包含多個服務層。微服務之間通過網絡進行通信,進而支撐 起整個應用系統。每一個服務并不保證一直都可用,當某一個服務的提供者不可用就會導緻服務的調用者不可用,進而将不可用放大的現象。

當出現雪崩效應後,整個服務都可能不可用,要想防止雪崩效應,必須有一個強大的容錯機制。

2 Hystrix簡介

Hystrix是一個用于處理分布式系統的延遲和容錯的開源庫,在分布式系統中,很多依賴不可避免的會調用失敗,比如逾時、異常等,Hystrix能夠保證一個依賴出問題後,不會導緻整體服務失敗,避免聯級錯誤,以提高分布式系統的彈性。

Hystrix三個重要概念:

        服務降級(fallback):伺服器忙,請稍後再試,不讓用戶端等待立即傳回一個友好提示。

        情況:

                1、程式運作異常

                2、逾時

                3、服務熔斷出發服務降級

                4、線程池/信号量打滿也會導緻服務降級

        服務熔斷(break):達到最大通路量時,直接拒絕通路,然後調用服務降級傳回友好提示。

                服務降級-->進而熔斷-->恢複調用鍊路

        服務限流(flowlimit):秒殺高并發操作時,禁止一起通路,排隊請求,有序進行。

3 Hystrix使用

3.1 服務降級(單個方法)

添加依賴

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
</dependency>
           

主啟動類添加@EnableHystrix注解,開啟Hystrix功能

@EnableHystrix
public class HystrixMain {
    public static void main(String[] args) {
        SpringApplication.run(HystrixMain.class,args);
    }
}
           

修改controller,為某一個方法添加容錯功能

@GetMapping("/hystrix/timeout/{id}")
 @HystrixCommand(fallbackMethod = "timeOutFallBackMethod",commandProperties = {
 //設定這個線程的逾時時間是3s,3s内是正常的業務邏輯,超過3s調用fallbackMethod指定的方法進行處理
   @HystrixProperty(name ="execution.isolation.thread.timeoutInMilliseconds",value = "3000")
  })
 public String test_TimeOut(@PathVariable("id") Integer id){
         try{
            TimeUnit.SECONDS.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
       return hystrixService.test_TimeOut(id);
    }

  public String timeOutFallBackMethod(@PathVariable("id") Integer id){
       return "系統逾時";
   }
           

3.2 服務降級(全局方法)

有時候為每個方法提供容錯功能挺麻煩,Hystrix提供一個可以設定全局fallback的功能。

給controller添加注解@DefaultProperties,并設定defaultFallback屬性,此屬性值為全局fallback方法名

@DefaultProperties(defaultFallback = "global_FallbackMethod")
public class HystrixController {

    //省略...

    /**
     * 全局 fallback 方法
     *
     */
    public String global_FallbackMethod(){
        return "全局fallback方法";
    }
}
           

3.3 服務降級(Feign實作)

在SpringCloud中,Feign實作fallback更加簡單,因為Spring Cloud預設已為Feign整合了 Hystrix。

修改application.yml為Feign開啟Hystrix

feign:
  hystrix:
    enabled: true
           

添加一個類實作Feign接口,專門處理fallback方法

@Component
public class FallbackService implements HystrixService {

    @Override
    public String test_TimeOut(Integer id) {
        return "Fegin fall back method";
    }
}
           

修改Fegin接口

@Component
//value值為服務提供者的服務名  fallback值為實作此接口的用于提供fallback方法的類
@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX-PAYMENT" ,fallback = FallbackService.class)
public interface HystrixService {

    @GetMapping("/payment/hystrix/timeout/{id}")
    public String test_TimeOut(@PathVariable("id") Integer id);
}
           

3.4 服務熔斷

當某個微服務不可用或者響應時間太長時,會進行服務的降級,進而熔斷該節點微服務的調用,快速傳回”錯誤”的響應資訊。在SpringCloud架構機制通過Hystrix實作,Hystrix會監控微服務見調用的狀況,當失敗的調用到一個門檻值,預設是5秒内20次調用失敗就會啟動熔斷機制,當檢測到該節點微服務響應正常後恢複調用鍊路。

controller添加一個方法,用于測試熔斷機制

//服務熔斷
    @GetMapping("/circuit/{id}")
    public String circuitBreaker(@PathVariable("id") Integer id){
        String result = circuitService.circuitBreaker(id);
        log.info("****result:"+result);
        return result;
    }
           

通過通路這個路徑,調用service對應的方法,如果滿足條件即可觸發熔斷

//服務熔斷
    @HystrixCommand(fallbackMethod = "circuitBreaker_fallback",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"),    //失敗率達到多少後跳閘
    })
    public String circuitBreaker(@PathVariable("id") Integer id){
        if(id < 0){
            throw new RuntimeException("******id 不能為負數");
        }
        String serialNumber = IdUtil.simpleUUID();  //UUID.randomUUID();

        return Thread.currentThread().getName()+"\t"+"調用成功,流水号:"+serialNumber;
    }
    public String circuitBreaker_fallback(@PathVariable("id") Integer id){
        return "id 不能負數,請稍後再試,o(╥﹏╥)o  id:"+id;
    }
           

解釋:可以看到@HystrixCommand注解中設定了幾個值,這說明在一個時間視窗期内,滿足規定的請求次數後并且達到失敗率就會觸發熔斷機制,打開斷路器,調用fallback方法。

requestVolumeThreshold(請求總數門檻值):在快照視窗期内,必須滿足請求總數門檻值才有資格熔斷。預設是20,也就是說在10秒内該Hystrix指令調用次數不足20次,即使所有的請求都失敗,斷路器也不會打開。

sleepWindowInMilliseconds(快照時間視窗):斷路器确定是否打開需要統計一些請求和錯誤資料,而統計的時間範圍就是快照時間視窗,預設為10秒。

errorThresholdPercentage(錯誤百分比門檻值):當請求總數在快照時間視窗内超過了門檻值,假設30次,其中有15次發生了錯誤,有50%的錯誤百分比,在預設設定50%的錯誤百分比門檻值情況下,斷路器就會打開。

在這個例子中,在10秒的視窗期内,10次請求中有6次id為負值的請求就會顯示fallback方法傳回的内容。當觸發熔斷機制後,即使id為正值也會調用fallback方法,不會進行請求的轉發。一段時間後(休眠時間視窗期,預設是5秒),這時候斷路器是半開狀态,讓一個請求進行轉發,如果成功斷路器關閉,服務恢複正常;失敗則繼續開啟。

注:當斷路器打開後将不會調用主邏輯,直接調用fallback方法。通過斷路器,實作了自動發現錯誤并從主邏輯切換到降級邏輯,減少響應延遲的效果。關于主邏輯的恢複,當斷路器打開對主邏輯熔斷後,Hystrix會啟動一個休眠視窗期,在這個時間内降級邏輯臨時成為主邏輯。當休眠時間視窗期到,斷路器進入半開狀态,釋放一次請求到主邏輯上。如果這次請求正常傳回,斷路器将關閉主邏輯恢複;如果這次請求依然出錯,斷路器繼續進入打開狀态,休眠時間視窗重新計時。

寫在最後,關于服務熔斷參考了相關教程後不知道自己了解的是否正确,如果有誤歡迎在評論區指出,謝謝。

參考連結:https://b23.tv/Ih97SA

繼續閱讀