Hystrix——服務(wù)容錯

1 Hystrix 簡介

在微服務(wù)架構(gòu)中叶圃,微服務(wù)之間通過網(wǎng)絡(luò)進行通信,存在相互依賴践图,當(dāng)其中一個服務(wù)不可用時掺冠,有可能會造成雪崩效應(yīng)。要防止這樣的情況码党,必須要有容錯機制來保護服務(wù)德崭。
Hystrix是Netflix開源的一個延遲和容錯庫,它主要實現(xiàn)了以下幾點:

  • 包裹請求
    使用HystrixCommand(或HystrixObservableCommand)包裹對依賴的調(diào)用邏輯揖盘,每個命令在獨立線程中執(zhí)行眉厨。
  • 跳閘機制
    當(dāng)某服務(wù)的錯誤率超過一定閾值時,Hystrix可以自動或手動跳閘扣讼,停止請求該服務(wù)一段時間缺猛。
  • 資源隔離
    Hystrix為每個依賴都維護了一個小型的線程池(或信號量),如果該線程池已滿椭符,發(fā)往該依賴的請求就被立即拒絕荔燎。
  • 監(jiān)控
    Hystrix可以近乎實時地監(jiān)控運行指標(biāo)和配置的變化。
  • 回退機制
    當(dāng)請求失敗销钝、超時有咨、被拒絕,或者當(dāng)斷路器打開時蒸健,執(zhí)行回退邏輯座享。
  • 自我修復(fù)
    當(dāng)斷路器打開一段時間后,會自動進入“半打開”狀態(tài)似忧,允許一個請求訪問依賴的服務(wù)渣叛,如果該請求成功,則關(guān)閉斷路器盯捌,否則繼續(xù)保持打開狀態(tài)淳衙。

2 整合Hystrix

2.1 Ribbon整合Hystrix

1.添加相應(yīng)的依賴:

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

2.在啟動類里添加@EnableCircuitBreaker 或者 @EnableHystrix注解

@EnableCircuitBreaker
@EnableDiscoveryClient
@SpringBootApplication
public class RibbonDemoApplication {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }



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

3.為需要容錯的方法添加@HystrixCommand注解,并使用fallbackMethod屬性指定回退方法

    @HystrixCommand(fallbackMethod = "errorFallback")
    @GetMapping("/hello")
    public String hello() {

        return this.restTemplate.getForObject("http://eureka-client-demo/hello", String.class);
    }


    public String errorFallback() {
        return "Error!";
    }

@HystrixCommand的配置類似下面:

@HystrixCommand(fallbackMethod = "stubMyService",
    commandProperties = {
      @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
    }
)

2.2 Feign使用Hystrix

1.Spring Cloud 中饺著,F(xiàn)eign默認已經(jīng)整合了Hystrix箫攀,所以只需要在配置中啟用Hystrix就會包裹全部Feign Client中的方法:

feign:
  hystrix:
    enabled: true

2.編寫回退方法,編寫一個Feign Client的實現(xiàn)類幼衰,在@FeignClient的fallback屬性指定對應(yīng)的類:

@FeignClient(name = "eureka-client-demo", fallback = ErrorFallback.class)
public interface DemoFeignClient {

    @GetMapping("/hello")
    public String hello();
}


@Component
public class ErrorFallback implements DemoFeignClient {

    @Override
    public String hello() {
        return "Error!";
    }
}

3.如果需要回退方法打印錯誤信息靴跛,可以使用fallbackFactory(fallback和fallbackFactory只能使用其中一種):

@FeignClient(name = "eureka-client-demo", fallbackFactory = ErrorFallbackFactory.class)
public interface DemoFeignClient {

    @GetMapping("/hello")
    public String hello();
}


@Component
public class ErrorFallbackFactory implements FallbackFactory<DemoFeignClient> {

    private static final Logger LOGGER = LoggerFactory.getLogger(ErrorFallbackFactory.class);

    @Override
    public DemoFeignClient create(Throwable throwable) {
        return new DemoFeignClient() {
            @Override
            public String hello() {
                //如果在create()中打印錯誤信息的話,在應(yīng)用程序啟動時就會打印
                ErrorFallbackFactory.LOGGER.info("fall back cause: ", throwable);
                return "Error!";
            }
        };
    }
}

4.如果不想某個Feign Client使用Hystrix的話渡嚣,可以使用如下配置:

@FeignClient(name = "eureka-client-demo", configuration = DisableHystrix.class)
public interface DemoFeignClient {

    @GetMapping("/hello")
    public String hello();
}

@Configuration
public class DisableHystrix {

    @Bean
    @Scope("prototype")
    public Feign.Builder feignBuilder() {
        return Feign.builder();
    }
}

3 Hystrix監(jiān)控

3.1 Ribbon中Hystrix的監(jiān)控

Hystrix提供了端點/hystrix.stream用于監(jiān)控Hystrix的情況梢睛,Ribbon在整合了Hystrix之后肥印,還需要引入Spring Boot 的actuator依賴,才能通過/hystrix.stream監(jiān)控接口運行情況绝葡。

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

/hystrix.stream的頁面會返回類似下面的監(jiān)控數(shù)據(jù):

data: {"type":"HystrixCommand","name":"hello","group":"Controller","currentTime":1516202320578,"isCircuitBreakerOpen":false,"errorPercentage":100,"errorCount":1,"requestCount":1,"rollingCountBadRequests":0,"rollingCountCollapsedRequests":0,"rollingCountEmit":0,"rollingCountExceptionsThrown":0,"rollingCountFailure":1,"rollingCountFallbackEmit":0,"rollingCountFallbackFailure":0,"rollingCountFallbackMissing":0,"rollingCountFallbackRejection":0,"rollingCountFallbackSuccess":1,"rollingCountResponsesFromCache":0,"rollingCountSemaphoreRejected":0,"rollingCountShortCircuited":0,"rollingCountSuccess":0,"rollingCountThreadPoolRejected":0,"rollingCountTimeout":0,"currentConcurrentExecutionCount":0,"rollingMaxConcurrentExecutionCount":0,"latencyExecute_mean":0,"latencyExecute":{"0":0,"25":0,"50":0,"75":0,"90":0,"95":0,"99":0,"99.5":0,"100":0},"latencyTotal_mean":0,"latencyTotal":{"0":0,"25":0,"50":0,"75":0,"90":0,"95":0,"99":0,"99.5":0,"100":0},"propertyValue_circuitBreakerRequestVolumeThreshold":20,"propertyValue_circuitBreakerSleepWindowInMilliseconds":5000,"propertyValue_circuitBreakerErrorThresholdPercentage":50,"propertyValue_circuitBreakerForceOpen":false,"propertyValue_circuitBreakerForceClosed":false,"propertyValue_circuitBreakerEnabled":true,"propertyValue_executionIsolationStrategy":"THREAD","propertyValue_executionIsolationThreadTimeoutInMilliseconds":1000,"propertyValue_executionTimeoutInMilliseconds":1000,"propertyValue_executionIsolationThreadInterruptOnTimeout":true,"propertyValue_executionIsolationThreadPoolKeyOverride":null,"propertyValue_executionIsolationSemaphoreMaxConcurrentRequests":10,"propertyValue_fallbackIsolationSemaphoreMaxConcurrentRequests":10,"propertyValue_metricsRollingStatisticalWindowInMilliseconds":10000,"propertyValue_requestCacheEnabled":true,"propertyValue_requestLogEnabled":true,"reportingHosts":1,"threadPool":"Controller"}

3.2 Feign中Hystrix的監(jiān)控

1.雖然Feign整合了Hystrix竖独,但是并沒有整合到監(jiān)控的模塊,所以我們需要重新引入依賴包:

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

2.在啟動類添加@EnableCircuitBreaker或者@EnableHystrix注解

@EnableCircuitBreaker
@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class FeignDemoApplication {

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

然后就可以通過端點/hystrix.stream查看監(jiān)控數(shù)據(jù)挤牛。

4 可視化監(jiān)控

4.1 監(jiān)控單個服務(wù)

可以使用hystrix-dashboard進行可視化監(jiān)控:
1.創(chuàng)建一個新項目,并引入以下依賴:

        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
        </dependency>
  1. 在啟動類加上@EnableHystrixDashboard注解
@EnableHystrixDashboard
@SpringBootApplication
public class HystrixDashboardApplication {

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

3.啟動應(yīng)用种蘸,打開/hystrix/端點墓赴,可以看到一下頁面:

hystix-dashboard.PNG

往url欄輸入/hystrix.stream的鏈接,如:http://localhost:8004/hystrix.stream航瞭,再點擊Monitor Stream按鈕诫硕,就可以看到如下圖的頁面:
hystix-dashboard-detail.PNG

4.2 監(jiān)控多個服務(wù)

上面的方法只能監(jiān)控單個服務(wù),如果要監(jiān)控多個服務(wù)刊侯,可以使用turbine章办,然后再使用hystrix-dashboard進行進行可視化監(jiān)控。
1.新建一個項目滨彻,引入turbine的依賴

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

2.在啟動類添加@EnableTurbine注解

@EnableTurbine
@SpringBootApplication
public class TurbineApplication {

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

3.配置文件:

server:
  port: 8006
spring:
  application:
    name: turbine
eureka:
  client:
    service-url:
      defaultZone: http://localhost:8001/eureka/
  instance:
    prefer-ip-address: true

turbine:
  app-config: feign-demo,ribbon-demo
  cluster-name-expression: "'default'"
  combine-host-port: true
  • app-config 指定需要監(jiān)控的服務(wù)藕届,用逗號分隔
  • cluster-name-expression 指定集群名稱
  • combine-host-port 按主機名和端口區(qū)分服務(wù),turbine默認相同host的為同一服務(wù)亭饵,將該屬性設(shè)為true后就可以按主機名和端口區(qū)分服務(wù)

4.啟動應(yīng)用休偶,打開/turbine.stream端點即可以看到兩者的監(jiān)控數(shù)據(jù)。這個時候辜羊,再將turbine的監(jiān)控數(shù)據(jù)接入hystrix-dashboard踏兜,比如,將url地址http://localhost:8006/turbine.stream填入dash-board的url一欄八秃,再點擊Monitor Stream按鈕碱妆,就可以同時看到兩個服務(wù)的監(jiān)控數(shù)據(jù)。

4.3 使用消息中間件收集數(shù)據(jù)(RabbitMQ)

  1. 提供服務(wù)的微服務(wù)添加以下依賴:
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-netflix-hystrix-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
  1. 添加RabbitMQ的配置:
spring:
  rabbitmq:
    host: localhost
    port: 5672
    username: guest
    password: guest
  1. Turbine項目移除turbine的依賴并添加以下依賴:
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-turbine-stream</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
        </dependency>
  1. 啟動類中@EnableTurbine修改為@EnableTurbineStream
  2. 添加RabbitMQ的配置昔驱,同2疹尾,同時去掉turbine的配置。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末舍悯,一起剝皮案震驚了整個濱河市航棱,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌萌衬,老刑警劉巖饮醇,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異秕豫,居然都是意外死亡朴艰,警方通過查閱死者的電腦和手機观蓄,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來祠墅,“玉大人侮穿,你說我怎么就攤上這事』汆拢” “怎么了亲茅?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長狗准。 經(jīng)常有香客問我克锣,道長,這世上最難降的妖魔是什么腔长? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任袭祟,我火速辦了婚禮,結(jié)果婚禮上捞附,老公的妹妹穿的比我還像新娘巾乳。我一直安慰自己,他們只是感情好鸟召,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布胆绊。 她就那樣靜靜地躺著,像睡著了一般欧募。 火紅的嫁衣襯著肌膚如雪辑舷。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天槽片,我揣著相機與錄音何缓,去河邊找鬼。 笑死还栓,一個胖子當(dāng)著我的面吹牛碌廓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播剩盒,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谷婆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了辽聊?” 一聲冷哼從身側(cè)響起纪挎,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎跟匆,沒想到半個月后异袄,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡玛臂,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年烤蜕,在試婚紗的時候發(fā)現(xiàn)自己被綠了封孙。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡讽营,死狀恐怖虎忌,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情橱鹏,我是刑警寧澤膜蠢,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站莉兰,受9級特大地震影響狡蝶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜贮勃,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望苏章。 院中可真熱鬧寂嘉,春花似錦、人聲如沸枫绅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽并淋。三九已至寓搬,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間县耽,已是汗流浹背句喷。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留兔毙,地道東北人唾琼。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓,卻偏偏與公主長得像澎剥,于是被迫代替她去往敵國和親锡溯。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354