天天看點

SpringCloud - Hystrix(三)

Hystrix 服務熔斷
SpringCloud - Hystrix(三)
SpringCloud - Hystrix(三)
SpringCloud - 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(為了達到降級效果),這裡模拟了一個奇數偶數判斷是為了模拟熔斷的場景。

繼續閱讀