六、熔斷器Hystrix

一、什么是Hystrix

??在分布式系統(tǒng)中,服務(wù)與服務(wù)之間的依賴錯綜復(fù)雜,一種不可避免的情況就是某些服務(wù)會 出現(xiàn)故障,導(dǎo)致依賴于它們的其他服務(wù)出現(xiàn)遠程調(diào)度的線程阻塞。Hystrix是Netflix 公司開源的一個項目,它提供了熔斷器功能,能夠阻止分布式系統(tǒng)中出現(xiàn)聯(lián)動故障。Hystrix是通過隔離服務(wù)的訪問點阻止聯(lián)動故障的,并提供了故障的解決方案,從而提高了整個分布式系統(tǒng)的彈性 。

二、Hystrix的設(shè)計原則

  • 防止單個服務(wù)的故障耗盡整個服務(wù)的 Servlet容器(例如 Tomcat)的線程資源。
  • 快速失敗機制,如果某個服務(wù)出現(xiàn)了故障,則調(diào)用該服務(wù)的請求快速失敗,而不是線程等待。
  • 提供回退( fallback)方案,在請求發(fā)生故障時,提供設(shè)定好的回退方案。
  • 使用熔斷機制,防止故障擴散到其他服務(wù)。
  • 提供熔斷器的監(jiān)控組件 Hystrix Dashboard,可以實時監(jiān)控熔斷器的狀態(tài) 。

三、Hystrix的工作機制

首先,當(dāng)服務(wù)的某個API接口的失敗次數(shù)在一定時間內(nèi)小于設(shè)定的閥值時,熔斷器處于關(guān)閉狀態(tài),該API接口正常提供服務(wù) 。當(dāng)該API接口處理請求的失敗次數(shù)大于設(shè)定的閥值時, Hystrix判定該API接口出現(xiàn)了故障,打開熔斷器,這時請求該 API 接口會執(zhí)行快速失敗的邏輯(即fallback回退的邏輯),不執(zhí)行業(yè)務(wù)邏輯,請求的線程不會處于阻塞狀態(tài)。處于打開狀態(tài)的熔斷器, 一段時間后會處于半打開狀態(tài),并將一定數(shù)量的請求執(zhí)行正常邏輯。剩余的請求會執(zhí)行快速失敗,若執(zhí)行正常邏輯的 請求失敗了,則熔斷器繼續(xù)打開 : 若成功了,則將熔斷器關(guān)閉。這樣熔斷器就具有了自我修 復(fù)的能力。


熔斷器機制

四、在RestTemplate和Ribbon上使用熔斷器

本節(jié)的案例在上一章的案例基礎(chǔ)之上進行改造。在上一章的 eureka-ribbon-client工程中, 我們使用RestTemplate調(diào)用了eureka-client的“刷” API接口, 并用Ribbon做了負(fù)載均衡,本節(jié)在此基礎(chǔ)上加Hystrix熔斷器的功能。
首先在工程的porn文件中引用Hystrix的起步依賴 spring-cloud-starter-hystrix,代碼 如下:

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

然后在 SpringBoot 的啟動類 EurekaRibbonClientApplication加上@EnableHystrix注解開啟 Hystrix 的熔斷器功能 ,代碼如下 :

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
public class EurekaRibbonClientApplication {

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

依次啟動工程eureka-server、eureka-client和eureka-ribbon-client。等所有的工程都啟動完 畢, 在瀏覽器上訪問 http://localhost:8674/hi?name=ben,瀏覽器會顯示:

關(guān)閉eureka-client,即它處于不可用的狀態(tài),此時 eureka-ribbon-client無法調(diào)用 eureka-client 的 “/hi"接口, 訪問http://localhost:8674/hi?name=ben,瀏覽器會顯示:

由此可見, 當(dāng)eureka-client不可用時,調(diào)用eureka-ribbon-client的“hi"接口會進入RibbonService類的“/hi”方法中。由于eureka-client沒有響應(yīng),判定 eureka-client不可用,開 啟了熔斷器,最后進入了fallbackMethod的邏輯。當(dāng)熔斷器打開了,之后的請求會直接執(zhí)行fallbackMethod的邏輯。這樣做的好處就是通過快速失敗,請求能夠得到及時處理,線程不再 阻塞。

五、在Feign上使用熔斷器

??由于Feign的起步依賴中已經(jīng)引入了Hystrix的依賴,所以在Feign中使用 Hystrix不需要引入任何的依賴。只需要在eureka-feign-client工程的配置文件application.yml 中配置開啟Hystrix的功能,配置文件application.yml中加以下配置:

feign:
  hystrix:
    enabled: true

??然后修改eureka-feign-client工程中的EurekaClientFeign代碼,在@FeignClient注解的fallback 配置加上快速失敗的處理類。該處理類是作為Feign熔斷器的邏輯處理類,必須實現(xiàn)被@FeignClient修飾的接口。 例如案例中的HiHystrix類實現(xiàn)了接口EurekaClientFeign,最后需要以SpringBean的形式注入IoC容器中。代碼如下:
@FeignClient(value = "eureka-client", configuration = FeignConfig.class, fallback = HiHystrix.class)
public interface EurekaFeignClient {
@GetMapping("/hi")
String sayHiFromEurekaClient(@RequestParam(value = "name") String name);
}

HiHystrix 作為熔斷器的邏輯處理類, 需要實現(xiàn)EurekaClientFeign 接口,井需要在接口方
法 sayHiFromEurekaClient()里 寫處理熔斷的具體邏輯,同時還需要在HiHystrix 類上加要在@Component 注解,注入 IoC 容器中。代碼如下 :

@Component
public class HiHystrix implements EurekaFeignClient {
    @Override
    public String sayHiFromEurekaClient(String name) {
        return "hi " + name + " sorry, error!";
    }
}

依次啟動工程eureka-server、eureka-client和eureka-feign-client。在瀏覽器上訪問http://localhost:8765/hi?name=ben,瀏覽器會顯示 :

關(guān)閉eureka-client,即它處于不可用的狀態(tài),此時eureka-feign-client無法調(diào)eureka-client
的“/hi”接口,在瀏覽器上訪問 http://localhost:8675/hi?name=ben ,瀏覽器會顯示 :

由此可見,當(dāng)eureka-client不可用時,eureka-feign-client進入了fallback的邏輯處理類(即HiHystrix),由這個類來執(zhí)行熔斷器打開時的處理邏輯 。

六、使用HystrixDashboard監(jiān)控熔斷器的狀態(tài)

在微服務(wù)架構(gòu)中 ,為了保證服務(wù)實例的可用性,防止服務(wù)實例出現(xiàn)故障導(dǎo)致線程阻塞,而出現(xiàn)了熔斷器模型。 烙斷器的狀況反映了一個程序的可用性和健壯性,它是一個重要指標(biāo)。HystrixDashboard是監(jiān)控Hystrix的熔斷器狀況的一個組件,提供了數(shù)據(jù)監(jiān)控和友好的圖形化展示界面。下面講述如何使用HystrixDashboard監(jiān)控熔斷器的狀態(tài)。

6.1 在RestTemplate中使用HystrixDashboard

改造上一節(jié)的工程,首先在 eureka-ribbon-client工程的 porn 文件上加上 Actuator 的起 步依賴、 HystrixDashboard的起步依賴和Hystrix的起步依賴,這3個依賴是必需的。 代碼 如下:

在程序的啟動類 EurekaRibbonClientApplication 加上@ EnableHystrixDashboard 開啟 Hystrix Dashboard 的功能, 完整的代碼如下 :

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

在程序的啟動類 EurekaRibbonClientApplication加上@EnableHystrixDashboard開啟Hystrix Dashboard的功能,完整的代碼如下 :

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {

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

依次啟動工程eureka-server、eureka-client和eureka-ribbon-client。在 瀏覽器上訪問 http://localhost: 8675/hi。
然后在瀏覽器上訪問 http://localhost:8674/hystrix.stream, 瀏覽器上會顯示熔斷器的數(shù)據(jù)指 標(biāo),如下圖所示。

在瀏覽器上訪問 http://localhost:8674/hystrix,瀏覽器顯示的界面如下圖所示。

在界面上依次填寫http://localhost:8674/hystrix.stream、2000、ben (這個可以隨意填寫),
單擊“ monitor”,進入頁面,如下圖所示。

在該頁面顯示了熔斷器的各種數(shù)據(jù)指標(biāo) , 這些數(shù)據(jù)指標(biāo)所表示的含義如下圖所示,該圖來自于Hystrix的官方文檔,更多信息可以查閱官方文檔,文檔地址 : https://github.com/Netflix/Hystrix/wiki/Dashboard

6.2 在Feign中使用Hystrix Dashboard

??同eureka-ribbon-client類似,eureka-feign-client工程的pom文件需要加上Actuator、Hystrix和HystrixDashboard的起步依賴。 依賴如下:

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

??需要在程序的啟動類EurekaFeignClientApplication加上注解@EnableHystrixDashboard開啟HystrixDashboard的功能。完整的代碼如下:

@SpringBootApplication
@EnableEurekaClient
@EnableHystrix
@EnableHystrixDashboard
public class EurekaRibbonClientApplication {

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

}

6.3 使用Turbine聚合監(jiān)控

??在使用HystrixDashboard組件監(jiān)控服務(wù)的熔斷器狀況時,每個服務(wù)都有一個 HystrixDashboard主頁,當(dāng)服務(wù)數(shù)量很多時,監(jiān)控非常不方便。為了同時監(jiān)控多個服務(wù)的熔斷器的狀況,Netflix開源了Hystrix的另一個組件Turbine。Turbine用于聚合多個HystrixDashboard, 將多個HystrixDashboard組件的數(shù)據(jù)放在一個頁面上展示,進行集中監(jiān)控。
??在上一節(jié)的例子上繼續(xù)進行改造,在主 Maven工程下新建一個Module工程,做為Turbine聚合監(jiān)控的工程,取名為eureka-monitor-client。首先, 在工程的pom文件引入工程所需的依賴,包括turbine、actuator和test的起步依賴,完整的代碼如下 :

@SpringBootApplication
@EnableEurekaClient
@EnableTurbine
public class EurekaMonitorClientApplication {
    public static void main(String[] args) {
        SpringApplication.run(EurekaMonitorClientApplication.class, args);
    }
}

??上述配置 代碼指 定了工程 的端口 號 為 8676,服務(wù)名為eureka-monitor-client。 turbine.aggregator. clusterConfig配置了需要監(jiān)控的服務(wù)名,如本例中的eureka-ribbon-client和eureka-feign-client,clusterNameExpression默認(rèn)為服務(wù)名的集群,此時用默認(rèn)的即可。turbine.aggregator.clusterConfig可以不寫,因為默認(rèn)就是default。最后指定了服務(wù)注冊中心的地址為 http:localhost:8761/eureka/。
??啟動工程eureka-server、eureka-client、eureka-feign-client、eureka-ribbon-client和eureka-monitor-client在瀏覽器上訪問 http://localhost:8674/hi?name=benhttp://localhost:8675/hi?name=ben。
在瀏覽器上打開網(wǎng)址 http://localhost:8675/hystrix,這個界面為HystrixDashboard界面。在界面上依次輸入監(jiān)控流的 Uri地址 http://localhost:8676/turbine.stream、監(jiān)控時間間隔 2000毫秒和 title,單擊 “monitor”,可以看到如下圖所示的界面

從上圖中可以看到,這個頁面聚合了eureka-ribbon-client和eureka-feign-client的HystrixDashboard數(shù)據(jù)。

總結(jié):本章主要學(xué)習(xí)了Hystrix熔斷器結(jié)合Feign和restTemplate調(diào)用服務(wù),以及使用HystrixDashboard和Trubine進行Hystrix監(jiān)控,后面繼續(xù)學(xué)習(xí)路由網(wǎng)關(guān)Zuul。

源代碼:https://github.com/Cheerman/macro-service.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容