Hystrix系列之入門

Hystrix是什么

在講Hystrix之前,應該先了解一下Netflix這家神奇的公司。

想必很多人都看過美劇《紙牌屋》,不過應該很少有人知道它的出品方就是Netflix,可以說是《紙牌屋》之父,同時愛奇藝、優(yōu)酷也是模仿Netflix的國內本土產品。作為一家在線影片租賃提供商,Netflix成立于1997年,在美國、加拿大提供互聯(lián)網(wǎng)隨選流媒體播放,定制DVD、藍光光碟在線出租業(yè)務,經(jīng)過多次商業(yè)模式的變革,Netflix成為了在線內容的霸主。據(jù)統(tǒng)計,Netflix在高峰期間的下載流量可以占到北美地區(qū)的1/3。

這里不得不提一點的是,從09年開始,Netflix逐漸把它的IT系統(tǒng)遷移到AWS云平臺上,并開始業(yè)務的轉型,從DVD租賃演變?yōu)樵诰€視頻供應商,依托于強大的AWS,這也給AWS帶來了巨大挑戰(zhàn)。

Netflix在AWS運行多年期間,總結了不少實踐經(jīng)驗,比如必須考慮到故障的可能性,在AWS云平臺上進行架構設計的一個經(jīng)驗法則是要作為一個悲觀主義者來設計應用架構:假設會出問題。

我們知道硬件總會發(fā)生故障,服務器會發(fā)生宕機,唯一不確定的就是在什么時候發(fā)生,所以在應用架構上要進行高可用設計,比如需要有一個清晰的數(shù)據(jù)備份和恢復機制,并自動化這個流程。

一個用戶看美劇看的好好的,后端提供該美劇的服務掛了,這時比較友好的方式是推送一部熱門的電影給用戶,這個動作即所謂的發(fā)生故障時的降級方案。

為此,Netflix API團隊在2011年啟動了彈性工程工作,即Hystrix,旨在通過控制那些訪問遠程系統(tǒng)、服務和第三方庫的節(jié)點,從而對延遲和故障提供更強大的容錯能力,提供了熔斷、隔離、Fallback、cache、監(jiān)控等功能,能夠在一個、或多個依賴同時出現(xiàn)問題時保證系統(tǒng)依然可用,目前它在Netflix每天處理著數(shù)百億的隔離線程以及數(shù)千億的隔離信號調用。

Hystrix是基于Apache License 2.0協(xié)議的開源的程序庫,目前托管在GitHub上。這個Star也是多的嚇人,足夠說明Hystrix的重要性。

什么場景可以使用

既然有了這么好的開源庫,必須得好好利用,那么具體都用在什么場景呢?下面以一個門票產品為例,大概描述一下使用場景。

在一個門票詳情的頁面中,可能最終依賴了很多個底層服務,比如推薦服務、評分服務、資源服務、優(yōu)惠服務、廣告服務等。仔細查看可以發(fā)現(xiàn),如果廣告、推薦、評分、優(yōu)惠等服務掛了,其實并不會影響整個下單流程,所以可以針對這些服務調用賦予熔斷降級的能力。

如果這些服務真的掛了,那么返回一個預設好的值即可,這樣用戶也幾乎察覺不出有什么異常。

如何使用Hystrix

目前Hystrix最新版本是1.5.13,在項目的pom文件中加上依賴

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-core</artifactId>
    <version>1.5.13</version>
</dependency>

Command方式

Hystrix提供了Command模式的接入方式,如果一個服務CommandHelloWorld需要熔斷降級的能力,那么只需要繼承Hystrix的HystrixCommand類,并重寫run方法和getFallback方法。

public class CommandHelloWorld extends HystrixCommand<String> {

    private final String name;

    public CommandHelloWorld(String name) {
        super(HystrixCommandGroupKey.Factory.asKey("ExampleGroup"));
        this.name = name;
    }

    @Override
    protected String run() {
        // 省略業(yè)務邏輯
        // 該方法可能會拋出異常
        return "Hello " + name + "!";
    }

    @Override
    protected String getFallback() {
        return "Hello Failure " + name + "!";
    }
}

這里需要注意的是,不能直接執(zhí)行run方法,這樣熔斷降級功能無法生效。
HystrixCommand內部提供了兩個方法:execute、queue
1、execute()
執(zhí)行HystrixCommand內部的execute方法,可以實現(xiàn)run方法的同步執(zhí)行

new CommandHelloWorld("hello").execute();

2、queue()
執(zhí)行HystrixCommand內部的queue方法,可以實現(xiàn)run方法的異步執(zhí)行

Future future = new CommandHelloWorld().queue();
String s = future.get();

如果依賴多個下游接口 ,通過異步方式,可以同時執(zhí)行,提高接口性能。

注解方式

如果覺得Command模式比較的繁瑣,Hystrix也提供了注解方式,不過必須引入hystrix-javanica,通過aspect的方式實現(xiàn)。

<dependency>
    <groupId>com.netflix.hystrix</groupId>
    <artifactId>hystrix-javanica</artifactId>
    <version>1.5.13</version>
</dependency>

并且在xml配置文件中加入

<aop:aspectj-autoproxy/>
<bean id="hystrixAspect" class="com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect"></bean>

下面是注解方式的Helloworld

@Component
public class HystrixHelloworld {

    @HystrixCommand(fallbackMethod = "fallback")
    public String run() {
        // 省略業(yè)務邏輯
        // 該方法可能會拋出異常
        return "Hello world!";
    }

    public String fallback() {
        return "fallback";
    }

在需要進行熔斷降級的方法上加@HystrixCommand注解,并指定fallbackMethod,這里需要注意的是,被指定的fallback方法,其返回和參數(shù)申明和主方法需要保持一致。

什么時候熔斷

默認情況下,如果run方法在運行期間,10秒總請求數(shù)超過20個,且有50%以上的請求發(fā)生異常,Hystrix內部會自動發(fā)生熔斷,并且執(zhí)行getFallback方法。

什么時候恢復

默認情況下,如果發(fā)生了熔斷,Hystrix內部每隔5s進行一次試探,即放過一個正常請求到后端服務,如果這個請求成功了,就算后端服務恢復了,Hystrix內部會自動關閉熔斷。

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

相關閱讀更多精彩內容

友情鏈接更多精彩內容