1. 程式人生 > 其它 >服務降級之Hystrix使用

服務降級之Hystrix使用

一、什麼是服務降級、服務熔斷和限流?

  複雜的分散式體系結構中服務之間的依賴較多,進行服務呼叫時不可避免出現呼叫失敗的情況,而且呼叫往往呈現鏈式呼叫,某一環節出現錯誤將會導致致命問題,產生可怕的“服務雪崩”效應,導致整個系統故障。為了解決上述這個問題,我們需要一定的手段來保證核心服務能夠正常執行,因此需要臨時丟棄或隔離這些出現問題的服務,這就是服務降級和熔斷。要注意的是服務降針對的是非核心服務,有些服務是不能進行降級和熔斷的,核心服務的熔斷和降級意味著整體業務體系無法使用,比如購物車結算服務等。

  服務降級和服務熔斷及限流是有區別的:

    1、降級體現在即使呼叫的服務出現問題時,任然向上級返回一個友好的提示(比如返回伺服器忙,請稍後再試),不向上級丟擲錯誤,不讓上級等待。程式執行異常、超時、服務熔斷觸發服務降級、執行緒池滿等情況都會導致服務降級。

    2、熔斷類似於保險絲,體現在當達到最大訪問負載後,直接跳閘拒絕服務,然後觸發降級方法返回友好的提示。

    3、限流體現在控制訪問併發量,嚴禁某一時間段內出現大量的訪問。

  在考慮降級之前,需要進行整體的業務系統分析,確保哪些服務是可以降級的。超時不再等待,宕機要有兜底解決方案......整理一套降級方案。常見的服務降級方案:訪問超時降級、頻率超限降級、服務故障降級、人工預警降級等。

二、什麼是Hystrix?

  Hystrix是一個用於處理分散式系統延遲和容錯的開源庫,它能保證在某一個服務出現問題的情況下,不會導致整體服務的聯級故障,以提高分散式系統的彈性。Hystrix支援服務降級、服務熔斷、實時監控、服務限流、隔離等功能,一般用於服務消費者模組中做降級(也可以用於服務提供者模組),但目前官網已停止更新,進入維護階段。

三、Hystrix的使用

  1、修改Pom檔案,引入jar包

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

  2、業務方法上增加@HystrixCommand(fallbackMethod = "falltHandler")註解,表示如果使用該註解的方法報錯了,就呼叫fallbackMethod 指定的兜底方法執行處理流程。

@HystrixCommand(fallbackMethod="falltHandler")
public
string methodserver()
{
int age = 10/0; return "嘗試呼叫微服務模組。。";
}
public string falltHandler()
{
return "伺服器錯誤,請稍後再試!";
}

  3、業務方法上增加@HystrixCommand(fallbackMethod = "falltHandler",commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds" , value="3000")})註解,表示如果使用該註解的方法執行超過3秒中,就呼叫fallbackMethod 指定的兜底方法執行處理流程。

@HystrixCommand(fallbackMethod = "falltHandler",commandProperties = {@HystrixProperty(name="execution.isolation.thread.timeoutInMilliseconds" , value="3000")})
public string methodserver()
{
  //等待3秒中...
   return "嘗試呼叫微服務模組。。";
}
public string falltHandler()
{
  return "對方伺服器超時,請稍後再試!";
}

  4、如果需要feign等元件支援Hystrix,還需要完成一下兩步

    a.主啟動類上增加@EnableCircuitBreaker註解

    b.在application.yml配置檔案中增加以下程式碼

feign:
   hystrix:
       enabled: true

四、全域性兜底方法配置

  以上程式碼的實現中,每個方法都對應一個兜底方法,這導致了程式碼膨脹,有時候很多方法可以公用一個預設兜底方法來進行處理,hystrix提供了一個註解@Defaultproperties(defaultFallback = “Global_FallbackMethod")來指定這個預設的兜底方法,該註解作用與類上。如果該類的方法上有指定的兜底方法則使用指定的兜底方法,否則使用這個預設的兜底方法。

@Restcontroller
@DefaultProperties(defaultFallback
= "global_FallbackMethod")
public class Hvstirxcontroller { public string global_FallbackMethod()
{
return "全域性兜底方法!";
}
}

五、微服務介面降級處理

  按照前面說的,都在業務方法上增加兜底方法,進行降級處理,也一定會導致程式碼臃腫,與其在Controller層對所有方法設定降級,還不如在呼叫微服務的介面類中去統一處理。Feign結合hystrix(要注意開啟結合功能,詳見前面介紹的開啟方法)提供了一種實現方式,實現步驟:

    1、新增一個類FallbackService實現微服務介面類,重寫微服務介面中方法。

    2、在微服務介面類上增加註解@FeignClient(value = "CLOUD-PROVIDER-HYSTRIX",fallback = FallbackService.class)。

  完成以上兩步設定後,微服務介面方法將以FallbackService類中重寫的方法作為它的兜底方法,當微服務介面方法調用出錯時,就會執行對應的重寫方法。

六、斷路器

  斷路器是Hystrix實現服務熔斷的一種機制,熔斷機制是應對服務雪崩的一種保護,當呼叫鏈路出現問題時,會先進行服務降級,進而熔斷該節點的呼叫,當檢測到節點恢復正常後,再次恢復鏈路呼叫。在SpringCloud框架中熔斷機制是通過Hystrix實現的,Hystrix會監控微服務的呼叫狀況。斷路器本身有三種狀態,開啟、關閉和半開狀態。當斷路器在開啟狀態不允許呼叫、在關閉狀態允許呼叫、半開狀態嘗試呼叫,若呼叫成功後狀態變成關閉狀態,反正變成開啟狀態。

  Hystrix中@HystrixCommand註解提供瞭如下幾個引數,用於配置斷路器

@HystrixCommand(
fallbackMethod = "CircuitBreaker_fallback",
commandProperties =
{ @HystrixProperty(name
= "circuitBreaker.enabled" , value = "true" ), @HlystrixProperty(name = "circuitBreaker.requestVolumeThreshold" ,value = "10"), @HystrixProperty(name = "circuitBreaker.sleepwindowInMi1liseconds" , value = "1000"),
@HlystrixProperty(name = "circuitBreaker.errorThresholdPercentage" , value = "60") })

  其中,fallbackMethod指定兜底方法,即當服務呼叫異常或斷路器狀態在開啟(與circuitBreaker.enabled指定的狀態概念不同)狀態時呼叫的處理方法。circuitBreaker.enabled指定是否啟用斷路器功能,circuitBreaker.requestVolumeThreshold指定請求次數峰值(達到峰值後跳閘),circuitBreaker.sleepwindowInMiliseconds指定時間間隔(統計峰值和失敗率的時間段),circuitBreaker.errorThresholdPercentage指定失敗率(失敗率達到後跳閘)。例子如下

//=====服務熔斷
@HystrixCommand(fallbacknethod = "circuitBreaker_fallback" ,commandProperties = {
@HystrixProperty(name = "circuitBreaker.enabled" , value =“true"),
@HystrixProperty(name = "circuitBreaker.requestvolumeThreshold",value = "100"),
@HystrixProperty(name = "circuitBreaker.sleepwindowInNi1liseconds" ,value = "1000"),
@HystrixProperty(name = "circuitBreaker.errorThresholdPercentage" ,value = "60")
})
public string CircuitBreaker(@Pathvariable("id") Integer id)
{
if(id < 0) { throw new RuntimeException(”*id不能負數");
}
return Thread.currentThread( ).getName( )+""\t"+"呼叫成功!";
}
public string circuitBreaker_fallback(@Pathvariable("id") Integer id) { return "id 不能負數,請稍後再試!";
}

  上述表示,在1秒鐘內如果呼叫失敗率達到60%或者請求達到峰值100次,則直接跳閘執行circuitBreaker_fallback方法。斷路器在開啟狀態時,隔一段時間(預設5秒)會將狀態轉換為半開狀態,後續請求會嘗試呼叫鏈路,若成功則將斷路器置為關閉狀態,正常執行CircuitBreaker方法,否則繼續將斷路器狀態變為開啟狀態,執行circuitBreaker_fallback方法。

  除了上述的基本配置功能外,Hystrix還提供了其他的配置項,請參考某大神的https://www.cnblogs.com/throwable/p/11961016.html,這裡不在詳述。

七、Hystrix服務監控儀表盤Dashboard

  Hystrix提供了實時的服務監控介面,Hystrix會持續第記錄所有通過Hystrix發起的請求,並以報表和圖形的形式展示給使用者,SpringCloud整合了HystrixDashboard,把監控的內容轉化成視覺化介面。

  建立Hystrix服務監控程式的步驟:1建立模組,2POM引入jar包,3配置yml配置檔案,4主啟動類上增加@EnableHystrixDashboard註解,5被監控的服務配置依賴,6啟動服務訪問服務地址顯示web視覺化介面。

   1、監控服務模組需要引入dashboard的jar包

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

  2、被監控的服務模組需要引入actuator的jar包,而且要在主啟動類上增加@EnablecircuitBreaker註解。

<! -- actuator監控資訊模組-->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

  注意:新版本springcloud的被監控服務模組需要在主啟動類下增加如下程式碼,否則可能導致無法顯示監控資料

/**
*此配置是為了服務監控而配置,與服務容錯本身無關,springcloud升級後的坑
*ServLetRegistrationBean因為springboot的預設路徑不是"/hbystcix.stream",*只要在自已的專案裡配置上下面的servlet就可以了
*/
@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;
}

  3、web視覺化頁面啟動成功後,在位址列輸入要監控的微服務的地址,即可對該服務實現監控,介面如下

八、Hystrix工作流程圖