Spring Boot + Spring Cloud 構建微服務系統(四):容錯機制和熔斷(Hystrix)

雪崩效應

在微服務架構中,因爲服務衆多,一般會涉及多個服務層級的調用,而一旦基礎服務發生故障,極可能會致使級聯故障,進而形成整個系統不可用,這種現象被稱爲服務雪崩效應。服務雪崩效應是一種因「服務提供者」的不可用致使「服務消費者」的不可用,並將這種不可用逐漸放大的過程。java

好比在一個系統中, A做爲服務提供者,B是A的服務消費者,C和D又是B的服務消費者。若是此時A發生故障,則會引發B的不可用,而B的不可用又將致使C和D的不可用,當這種不可用像滾雪球同樣逐漸放大的時候,雪崩效應就造成了。git

熔斷器(CircuitBreaker)

熔斷器的原理很簡單,如同電力過載保護器。它能夠實現快速失敗,若是它在一段時間內偵測到許多相似的錯誤,就會強迫其之後的多個調用快速失敗,再也不訪問遠程服務器,從而防止應用程序不斷地嘗試執行可能會失敗的操做,使得應用程序繼續執行而不用等待修正錯誤,或者浪費CPU時間去等到長時間的超時產生。熔斷器也可使應用程序可以診斷錯誤是否已經修正,若是已經修正,應用程序會再次嘗試調用操做。熔斷器模式就像是那些容易致使錯誤的操做的一種代理。這種代理可以記錄最近調用發生錯誤的次數,而後決定使用容許操做繼續,或者當即返回錯誤。熔斷器是保護服務高可用的最後一道防線。web

Hystrix特性

1.斷路器機制spring

斷路器很好理解, 當Hystrix Command請求後端服務失敗數量超過必定比例(默認50%), 斷路器會切換到開路狀態(Open). 這時全部請求會直接失敗而不會發送到後端服務. 斷路器保持在開路狀態一段時間後(默認5秒), 自動切換到半開路狀態(HALF-OPEN). 這時會判斷下一次請求的返回狀況, 若是請求成功, 斷路器切回閉路狀態(CLOSED), 不然從新切換到開路狀態(OPEN). Hystrix的斷路器就像咱們家庭電路中的保險絲, 一旦後端服務不可用, 斷路器會直接切斷請求鏈, 避免發送大量無效請求影響系統吞吐量, 而且斷路器有自我檢測並恢復的能力。後端

2.Fallback緩存

Fallback至關因而降級操做. 對於查詢操做, 咱們能夠實現一個fallback方法, 當請求後端服務出現異常的時候, 可使用fallback方法返回的值. fallback方法的返回值通常是設置的默認值或者來自緩存。服務器

3.資源隔離架構

在Hystrix中, 主要經過線程池來實現資源隔離. 一般在使用的時候咱們會根據調用的遠程服務劃分出多個線程池. 例如調用產品服務的Command放入A線程池, 調用帳戶服務的Command放入B線程池. 這樣作的主要優勢是運行環境被隔離開了. 這樣就算調用服務的代碼存在bug或者因爲其餘緣由致使本身所在線程池被耗盡時, 不會對系統的其餘服務形成影響. 可是帶來的代價就是維護多個線程池會對系統帶來額外的性能開銷. 若是是對性能有嚴格要求並且確信本身調用服務的客戶端代碼不會出問題的話, 可使用Hystrix的信號模式(Semaphores)來隔離資源。app

Feign Hystrix

由於 Feign 中已經依賴了 Hystrix, 因此在 maven 配置上不用作任何改動就可使用了,咱們在 spring-cloud-consul-consumer 項目中直接改造。負載均衡

修改配置

在配置文件中添加配置,開啓 Hystrix 熔斷器。

application.yml

#開啓熔斷器
feign:
  hystrix:
    enabled: true

建立回調類

建立一個回調類 FeignHelloHystrix,實現 FeignHelloService 接口,並實現對應的方法,返回調用失敗後的信息。

FeignHelloHystrix.java

package com.louis.spring.cloud.consul.consumer.service;

import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;

@Component
public class FeignHelloHystrix implements FeignHelloService {

    @RequestMapping("/hello")
    public String hello() {
        return "sorry, this service call failed.";
    }
}

添加fallback屬性

修改 FeignHelloService,在 @FeignClient 註解中加入 fallback 屬性,綁定咱們建立的失敗回調處理類。

package com.louis.spring.cloud.consul.consumer.service;

import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;

@FeignClient(name = "service-producer", fallback = FeignHelloHystrix.class)
public interface FeignHelloService {

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

到此,全部改動代碼就完成了。

測試效果

爲了方便測試,咱們把負載均衡策略修改成輪詢模式。

啓動成功以後,屢次訪問 http://localhost:8521/feign/call,結果如同以前同樣交替返回 hello consul 和 hello consul two。

說明熔斷器的啓動,不會影響正常服務的訪問。

 如今手動把 spring-cloud-consul-producer 的服務停掉,再次訪問,返回咱們提供的熔斷回調信息,熔斷成功。

重啓 spring-cloud-consul-producer 服務,再次訪問,發現服務又能夠訪問了,說明熔斷器具備自我診斷修復的功能。

注意:在重啓成功以後,可能須要一些時間,等待熔斷器進行自我診斷和修復完成以後,方可正常提供服務。

 

 

源碼下載

碼雲:https://gitee.com/liuge1988/spring-cloud-demo.git


做者:朝雨憶輕塵
出處:https://www.cnblogs.com/xifengxiaoma/ 版權全部,歡迎轉載,轉載請註明原文做者及出處。

相關文章
相關標籤/搜索