Spring Cloud (7) —— Hystrix 熔斷、降級、隔離

關於 Hystrix

  1. 熔斷web

    • 熔斷是 consumer 角色一側的功能。
    • 當請求某一 provider 的失敗狀況達到某一閥值後,斷路器會切換到 open 狀態,請求將再也不發往這個 provider 。
    • 斷路器打開一段時間後,會切換到 half-open 狀態,此時斷路器的狀態將取決於下一次請求是否成功。若是成功,則切換到 closed 狀態;若是失敗,則切換到 open 狀態。
  2. 服務降級 Fallback
    當處理出現異常,或不具有處理能力時(負載太高、線程池用完),則會快速返回一個預先指定的值。
  3. 資源隔離
    資源隔離主要用來預防雪崩的發生,限制某一資源不可用引發的全局資源掛起。可選的隔離方式有 線程隔離、信號量隔離。

熔斷 和 降級

在通常方法上應用

  1. 建立模塊 spring-cloud.s05.store-hystrix
  2. pom 中添加依賴spring

    <dependencies>
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
        <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
      </dependencies>
  3. 添加配置文件app

    server:
      port: 31003
    spring:
      application:
        name: store-hystrix
    eureka:
      client:
        serviceUrl:
          defaultZone: http://user:123123@localhost:34001/eureka/
      instance:
        instance-id: ${spring.cloud.client.ip-address}:${server.port}
        prefer-ip-address: true
        lease-renewal-interval-in-seconds: 10
        lease-expiration-duration-in-seconds: 30
    info:
      app.name: ${spring.application.name}
      compony.name: me.xhy
      build.artifactId: $project.artifactId$
      build.modelVersion: $project.modelVersion$
  4. 建立啓動類 ..StoreHystrix負載均衡

    @SpringBootApplication
    @EnableEurekaClient
    // 開啓降級
    @EnableHystrix
    public class StoreHystrix {
    
      public static void main(String[] args) {
        SpringApplication.run(StoreHystrix.class, args);
      }
    
      @Bean
      @LoadBalanced
      RestTemplate restTemplate() {
        return new RestTemplate();
      }
    }
    若是啓動類中 不寫 @EnableHystrix 註解,那麼當方法失敗時,是不會執行降級方法的;可是註解了 @HystrixCommand 的方法是能夠有熔斷功能的,默認值也依然是 3次, 當失敗次數達到3次時,在 ribbon 中剔除該資源。
  5. 建立程序訪問入口..ConsumerCircuitControlleride

    @RestController
    @RequestMapping("/hystrix")
    public class CircuitFallbackController {
    
      @Autowired
      RestTemplate restTemplate;
    
      /*
      新增了 @HystrixCommand
      @HystrixCommand(fallbackMethod = "getMoviesError") 默認鍵爲 fallbackMethod
      表示當調用 provider 失敗,調用的補償方法
      默認狀況下,發生3次錯誤(補償方法調用了3次),該 provider 將被熔斷
      當被熔斷的 provider 從新上線,將被從新加回到服務列表
      */
      @RequestMapping("/cf/ribbon")
      @HystrixCommand(fallbackMethod = "getServerPortError")
      public String getServerPort() {
        return restTemplate.getForObject("http://album-provider/album/server-port", String.class);
      }
    
      public String getServerPortError() {
        return "ribbon method getMovies occur hystrix";
      }
    
      @RequestMapping("/cf/always-exception")
      @HystrixCommand(fallbackMethod = "getServerPortError")
      public String alwaysException() {
        if(true) throw new RuntimeException();
        return "hi";
      }
    }

    這個 Controller 中有兩個訪問入口, @RequestMapping("/circuit/always-exception") 始終都會發生異常;@HystrixCommand(fallbackMethod = "getServerPortError") 則須要在正常訪問全部 provider 後,停掉至少一個 provider 來觀察結果。spring-boot

  6. 驗證熔斷和降級ui

    • http://localhost:31003/hystrix/circuit/always-exception 因爲該 Controller 始終報錯,因此始終使用降級方法的返回值。
    • http://localhost:31003/hystrix/circuit/ribbon 使用 ribbon 的負載均衡訪問 provider ,下線至少一個 provider 來觀察效果。
    啓動類註解了 @EnableHystrix 服務降級纔會生效。 @HystrixCommand 只有在應用 ribbon 的方法上,纔會有熔斷效果。

在 Feign 上應用

Feign 是自帶斷路器的,可是它沒有默認打開。須要在配置文件中配置打開它線程

  1. pom 中引入 Feignrest

    <dependency>
          <groupId>org.springframework.cloud</groupId>
          <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
  2. 在配置文件中打開斷路器code

    feign:
      hystrix:
        enabled: true
  3. 啓動類增長註解

    @EnableFeignClients // Feign 須要
  4. 建立 Feign 接口

    @FeignClient(value = "album-provider", fallback = CircuitFallbackFeignServiceFallback.class)
    public interface CircuitFallbackFeignService {
    
      @RequestMapping("/album/server-port")
      String getServerPort();
    
    }
    
    /*
    該類提供發生異常時的補償方法
    必需要有 @Component , 能夠是外部類
     */
    @Component
    class CircuitFallbackFeignServiceFallback implements CircuitFallbackFeignService {
      @Override
      public String getServerPort() {
        return "feign method getServerPort occur hystrix";
      }
    }
  5. 建立訪問程序入口 ..CircuitFallbackFeignController

    @RestController
    @RequestMapping("/hystrix")
    public class CircuitFallbackFeignController {
    
      @Autowired
      CircuitFallbackFeignService service;
    
      @RequestMapping("/cf/feign")
      public String getServerPort() {
        return service.getServerPort();
      }
    }
  6. 訪問 http://localhost:31003/hystrix/cf/feign

    若是配置文件中不開啓斷路器,降級方法是不會執行的
    若是配置文件中不設置重重試次數,feign 默認會重試 1 次

隔離

隔離能夠防止雪崩的出現。當 provider 沒有足夠的處理能力時, consumer 的請求沒法返回致使線程掛起,逐層影響,最終雪崩。若是限制 consumer 請求某個 provider 的 , consumer 就不會由於 provider 喪失處理能力而掛起過多的線程, consumer 仍然能夠保持服務能力,去作其餘任務。

使用線程隔離

使用信號量隔離

相關文章
相關標籤/搜索