天天看點

一起來學SpringCloud 斷路器Hystrix

序言

在微服務架構中,根據業務來拆分成一個個的服務,服務與服務之間可以通過

RPC

互相調用,在 Spring Cloud 中可以用

RestTemplate + Ribbon

Feign

來調用。為了保證其高可用,單個服務通常會叢集部署。由于網絡原因或者自身的原因,服務并不能保證 100% 可用,如果單個服務出現問題,調用這個服務就會出現線程阻塞,此時若有大量的請求湧入,

Servlet

容器的線程資源會被消耗完畢,導緻服務癱瘓。服務與服務之間的依賴性,故障會傳播,會對整個微服務系統造成災難性的嚴重後果,這就是服務故障的 “雪崩” 效應。 為了解決這個問題,業界提出了熔斷器模型。

Netflix 開源了 Hystrix 元件,實作了熔斷器模式。

此文章僅限入門 SpringCloud版本為 Greenwich

當然 Hystrix 已經進入維護階段了,也就是說不再會有新功能産出,但是已經足夠成熟。Spring Cloud 正在孵化自己的熔斷器 Resilience4j ,最近阿裡的 Sentinel 也釋出了可用于生産的版本。

使用

首先呢加入如下依賴

<dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <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-openfeign</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
    </dependencies>
           

在yml裡配置一下注冊中心

server:
  port: 7001
spring:
  application:
    name: spring-cloud-action-server-order
eureka:
  instance:
    prefer-ip-address: true
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}}
    hostname: localhost
  client:
    service-url:
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
           

然後呢是啟動類

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ATestApplication.class, args);
    }
}

           

其實還有一個注解可以 同時包含

@EnableDiscoveryClient 、@EnableDiscoveryClient、@EnableHystrix

換成

@SpringCloudApplication

就行了

@SpringCloudApplication
@EnableFeignClients
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}
           

在Ribbon中使用

在 Ribbon 調用方法上增加

@HystrixCommand

注解并指定

fallbackMethod

熔斷方法

@RestController
public class OrderController {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "getProductsError")
    @GetMapping
    public String getOrder() {
        return restTemplate.getForObject("http://SPRING-CLOUD-ACTION-SERVER-B/getProducts, String.class);
    }

    public String getProductsError(String message) {
        return "Hi,your request error.";
    }
}
           

怎麼測試呢? 當我關閉

spring-cloud-action-server-product

服務時,通路

@HystrixCommand

注解标注的接口時候,我們發現直接傳回了

getProductsError

裡的内容,就表示服務已經熔斷。

這裡說一點進階用法,如果想使用Hystrix 的詳細配置,可以 使用

@HystrixCommand

commandProperties

屬性與

@HystrixProperty

注釋清單一起使用 。

比如設定一個逾時

@HystrixCommand(commandProperties = {
    @HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "15000")
    }
)
           

或者這樣使用

Hystrix 還而已認證信号量來實作限流,等功能,具體可以在 其 github倉庫的wiki 裡詳細的看到。

Feign 中使用熔斷器

Feign 是自帶熔斷器的,但預設是關閉的。需要在配置檔案中配置打開它,在配置檔案增加以下代碼

feign:
  hystrix:
    enabled: true
           

然後在Feign的接口中增加forback指定類

@FeignClient(value = "spring-cloud-action-server-product",fallback =ProductService.FallbackProductService.class )
public interface ProductService {
    @GetMapping("/getProducts")
    String getProducts();
   
    @Component
    class FallbackProductService implements ProductService {
        @Override
        public String query() {
            return "通路出現問題";
        }
    }
}

           

然後在調用Feign的時候也就會帶有熔斷的效果啦。

儀表盤

除了隔離依賴服務的調用以外,Hystrix還提供了近實時的監控,Hystrix會實時、累加地記錄所有關于HystrixCommand的執行資訊,包括每秒執行多少請求多少成功,多少失敗等。Netflix通過

hystrix-metrics-event-stream

項目實作了對以上名額的監控。

添加依賴

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

然後在啟動類中加入

@SpringCloudApplication
@EnableFeignClients
@EnableHystrixDashboard
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class, args);
    }
}
           

然後加入

HystrixMetricsStreamServlet

的配置

@Configuration
public class HystrixDashboardConfig {

    @Bean
    public ServletRegistrationBean getServlet() {
        HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
        ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
        registrationBean.setLoadOnStartup(1);
        registrationBean.addUrlMappings("/hystrix.stream");
        registrationBean.setName("HystrixMetricsStreamServlet");
        return registrationBean;
    }
}
           

打開項目 通路

http://localhost:7001/hystrix

就可以啦

一起來學SpringCloud 斷路器Hystrix

輸入相應的玩意設定一下标題就可以進入控制台了,隻要觸發了

Hystrix

熔斷 就會顯示在控制台中。

一起來學SpringCloud 斷路器Hystrix

給一個詳細的說明圖解

一起來學SpringCloud 斷路器Hystrix

什麼情況下會觸發

fallback

方法

名字 描述 觸發fallback
EMIT 值傳遞 NO
SUCCESS 執行完成,沒有錯誤 NO
FAILURE 執行抛出異常 YES
TIMEOUT 執行開始,但沒有在允許的時間内完成 YES
BAD_REQUEST 執行抛出HystrixBadRequestException NO
SHORT_CIRCUITED 斷路器打開,不嘗試執行 YES
THREAD_POOL_REJECTED 線程池拒絕,不嘗試執行 YES
SEMAPHORE_REJECTED 信号量拒絕,不嘗試執行 YES

fallback

方法在什麼情況下會抛出異常

名字 描述 抛異常
FALLBACK_EMIT Fallback值傳遞 NO
FALLBACK_SUCCESS Fallback執行完成,沒有錯誤 NO
FALLBACK_FAILURE Fallback執行抛出出錯 YES
FALLBACK_REJECTED Fallback信号量拒絕,不嘗試執行 YES
FALLBACK_MISSING 沒有Fallback執行個體 YES

注意

Hystrix在執行他的邏輯的時候,其實做了來回的線程切換,是以說很容易導緻一些問題,比如ThreadLocal 或者 Spring 聲明式事物的失效。是以是用需要仔細考慮。

此文章僅限入門,切記啊不會用找不到多去官網看文檔!

繼續閱讀