Springcloudalibaba之Sentinel服務熔斷與限流


一、什么是Sentinel?

  它是分布式系統的流量防衛兵,與Hystrix的作用一樣,它能保證在某一個服務出現問題的情況下,不會導致整體服務的聯級故障,以提高分布式系統的彈性。它是hystrix的替代品。比起hystrix來說,Sentinel可以通過web界面來進行更加細粒度的配置流控、速率控制、服務熔斷、服務降級。Sentinel組件由Java客戶端和Dashboard構成。sentinel生態圈和主要功能特性如下

   二、Sentinel使用

  1、安裝和啟動: 去https://github.com/alibaba/Sentinel/releases下載sentinel-dashboard-1.8.2.jar包,運行前需要安裝Java8環境,切換到jar包目錄cmd執行 java -jar sentinel-dashboard-1.8.2.jar即可啟動。訪問http://localhost:8080即可顯示web控制台登錄界面(默認賬號密碼sentinel)。

   2、創建服務模塊

    a.引入jar包

< ! --Springcloud ailibaba sentinel -->
<dependency>
  <groupId>com.alibaba.cloud</groupId>
  <artifactId>spring-cloud-starter-alibaba,sentinel</artifactId>
</dependency>

    b.修改yml配置文件,配置Sentinel dashboard地址

server:
  port: 8401

spring:
   application:
       name: cloudalibaba-sentinel-service
   cloud:
       nacos:
          discovery:
             server-addr: localhost:8848
       sentinel:
           transport:
               #配置sentinel dashboard地址
               dashboard: localhost:8080
              #默認8719端口,假如被占角會自動從8719開始依次+1掃描,直至找到未被占用的端口
               port: 8719

management:
    endpoints:
       web:
          exposure:
              include: "*"

    c.編寫微服務接口Controller,到此sentinel監控搭建完,訪問sentinel控制台,即可顯示被監控的8848微服務(sentinel懶加載-需要先調用一次8848服務接口才能顯示)。界面如下

三、Sentinel流控規則

  Sentinel支持流量控制,它監控應用流量的QPS或並發線程數等指標,當達到指定閾值時對流量進行控制,避免系統被瞬時的流量高峰沖垮,保障應用高可用性。

    1.閾值類型:

      QPS:每秒請求數,當前調用該api的QPS到達閾值的時候進行限流。

            線程數:當調用該api的線程數到達閾值的時候,進行限流。

    2.流控模式:

      直接:當api大達到限流條件時,直接限流

      關聯:當關聯的資源到達閾值,就限流自己

      鏈路:只記錄指定路上的流量,指定資源從入口資源進來的流量,如果達到閾值,就進行限流,api級別的限流

    3.流控效果:

      快速失敗:直接返回失敗、拋異常

      預熱(WarmUP):當系統長期處於低水位的情況下,當流量突然增加時,直接把系統拉升到高水位可能瞬間把系統壓垮。通過"冷啟動",讓通過的流量緩慢增加,在一定時間內逐漸增加到閾值上限,給冷系統一個預熱的時間,避免冷系統被壓垮。

      排隊等待:會嚴格控制請求通過的間隔時間,也即是讓請求以均勻的速度通過,對應的是漏桶算法。

  以下配置界面:

 四、Sentnel熔斷降級

  Sentinel熔斷降級會在調用鏈路中某個資源出現不穩定狀態時(例如調用超時或異常比例升高),對這個資源的調用進行限制,讓請求快速失敗,避免影響到其它的資源而導致級聯錯誤。當資源被降級后,在接下來的降級時間窗口之內,對該資源的調用都自動熔斷(默認行為是拋出 DegradeException)。Sentinel降級策略包含平均響應時間RT、異常比例、異常數。

  平均響應時間(DEGRADE_GRADE_RT):當1s內持續進入5個請求,對應時刻的平均響應時間(秒級)均超過閾值( count,以ms為單位),那么在接下的時間窗口(以s為單位)之內,對這個方法的調用都會自動地熔斷(拋出DegradeException )。注意Sentinel默認統計的RT上限是4900 ms,超出此閾值的都會算作4900ms,若需要變更此上限可以通過啟動配置項-Dcsp.sentinel.statistic.max.rt=xx來配置。

  異常比例( DEGRADE_GRADE_EXCEPTION_RATIo ):當資源的每秒請求量>=5,並且每秒異常總數占通過量的比值超過閾值( DegradeRule 中的 count)之后,資源進入降級狀態,即在接下的時間窗口( DegradeRule中的 timewindow,以s為單位)之內,對這個方法的調用都會自動地返回。異常比率的閾值范圍是[0.0,1.0],代表0% - 100%。

  異常數( DEGRADE_GRADE_EXCEPTION_coUNT ):當資源近1分鍾的異常數目超過閾值之后會進行熔斷。注意由於統計時間窗口是分鍾級別的,若 timevindow小於60s,則結束熔斷狀態后仍可能再進入熔斷狀態。

  以下是配置界面:

 五、熱點參數限流

  熱點即經常訪問的數據。很多時候我們希望統計某個熱點數據中訪問頻次最高的TopK數據,並對其訪問進行限制。比如:·用戶ID為參數,針對一段時間內頻繁訪問的用戶ID進行限制。

  熱點參數限流會統計傳入參數中的熱點參數,並根據配置的限流閾值與模式,對包含熱點參數的資源調用進行限流。熱點參數限流可以看做是一種特殊的流量控制,僅對包含熱點參數的資源調用生效。

  1、啟用熱點參數限流功能:

    a.在服務模塊中引入如下依賴:

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-parameter-flow-control</artifactId> 
</dependency>

    b.為對應的資源接口配置熱點參數限流規則,在調用的時候傳入相應的參數,即可使熱點參數限流生效。舉例如下:

@GetMapping("/getHotKey") 
@SentinelResource(value = "testHotKey" ,blockHandler = "deal_testHotKey")  //blockHandler指定兜底方法,value指定資源名
public string getHotKey(@RequestParam(value = "p1") string p1,@RequestParam(value = "p2") string p2) 
{  
  return "------testHotKey" ; 
}
public string deal_testHotKey (string p1,string p2,BlockException exception)
{
  return "------deal_testHotKey,o(T-T)o" ;
}

     結合以上代碼和配置規則,表示:當請求http://localhost:8401/getHotKey?p1=xxxx&p2=xxx資源接口的時候,如果該方法第一個參數每秒的QPS超過1次,就馬上降級調用兜底方法deal_testHotKey 。(如果不配置blockHandler,會使用系統默認的兜底方法返回Blocked by Sentinel (flow limiting)或將異常顯示到前台,不推薦這樣做)

   2、限流規則中參數例外項:在1中,當熱點參數是某個特殊值的時候,我們要求不降級限流怎么辦?配置規則里提供了參數例外項來解決這個問題,具體如下,通過添加規則組來對每個特殊值添加不同的閾值。 

六、系統規則

  系統保護規則是從應用級別的入口流量進行控制,從單台機器的load、CPU使用率、平均RT、入口QPS和並發線程數等幾個維度監控應用指標,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。系統保護規則是應用整體維度的,而不是資源維度的,並且僅對入口流量生效。入口流量指的是進入應用的流量( EntryType.IN ),比如Web服務或Dubbo服務端接收的請求,都屬於入口流量。系統規則支持以下模式:

  1、Load自適應(僅對 Linux/Unix-like機器生效):系統的load1作為啟發指標,進行自適應系統保護。當系統load1超過設定的啟發值,且系統當前的並發線程數超過估算的系統容量時才會觸發系統保護(BBR階段)。系統容量由系統的 maxQps * minRt估算得出。設定參考值一般是CPu cores * 2.5。

  2、CPU使用率(1.5.0+版本)︰當系統CPU使用率超過閾值即觸發系統保護(取值范圍0.0-1.0) ,比較靈敏。

  3、平均RT:當單台機器上所有入口流量的平均RT達到閾值即觸發系統保護,單位是毫秒。

  4、並發線程數:當單台機器上所有入口流量的並發線程數達到閾值即觸發系統保護。

  5、入口QPS:當單台機器上所有入口流量的QPS達到閾值即觸發系統保護。

  規則配置如圖:

 七、自定義限流處理邏輯

  在編碼過程中,我們通常需要將業務邏輯與異常處理代碼分離,實現解耦。在上面的例子中業務邏輯代碼和兜底方法在同一個類中,顯然不合適,sentinel提供的注解@SentinelResource注解提供了一個blockHandelClass特性能夠方便我們進行代碼分離。實現過程如下:

  1、創建一個專門的兜底方法類CustomerBlockHandler

public class  CustomerBlockHandler
{
public static CommonResult handleException(BlockException exception)
{
return new CommonResult( code: 200,message:"自定義的限流處理信息");
}
public static commonResult handleException2(BlockException exception)
{
return new CommonResult( code: 200,message:"自定義的限流處理信息2");
}
}

  2、在資源接口方法上增加注解@SentinelResource(value = "customerBlockHandler",blockHandlerclass= CustomerBlockHandler.class,blockHandler = "handleException”)

@GetMapping("/rateLimit/customerBlockHandler")
@SentinelResource(value = "customerBlockHandler", blockHandlerclass = customerBlockHandler.class, //指定兜底類
blockHandler= "handlerException") //指定兜底類中的兜底方法 public commonResult customerBlockHandler()
{
return new CommonResult( code: 200,message:"按客戶自定義" , new Payment(id: 2020L,serial:."serial003"));
}

 八、資源接口邏輯異常處理

  前面的@SentinelResource的blockHandler指定方法只用於不滿足sentinel控制台配置規則時的兜底,本身並不處理資源接口的異常,該注解提供了另外一個特性fallback,用於指定資源接口內部異常時要執行的兜底方法。例如

@sentinelResource(value = "fallback" ,fallback = "handlerFallback")  //fallback只負責業務異常
public commonResult<Payment> fallback(@Pathvariable Long id)
{
      CommonResult<Payment> result =restTemplate.getForobject(url:SERVICE_URL + "/paymentsQL/"+id ,commonResult.class,id);
    if (id == 4) 
    {
         throw new IllegalArgumentException ("IllegalArgumentException,非法參數異常....");
    }
    return result;
}

//業務邏輯異常時執行
public CommonResult handlerFallback(@Pathvariable Long id, Throwable e) { Payment payment = new Payment(id, serial: "nu1l"); return new CommonResult<>( code: 44, message:"兜底異常FandlerFallback,exception內容"+t .getMessage(), payment); }

  異常忽略:sentinel提供了一個特性exceptionsToIgnore = {illegalArgumentException.class}用於忽略資源接口異常,表示如果觸發該類型的異常,就不再用fallback兜底,不會觸發降級,讓其自行處理后續。

九、Sentinel規則持久化

  前面的規則配置在微服務重啟后會丟失,也就是說他們的配置是臨時的,我們需要對這些業務規則進行持久化。我們將限流規則持久化進nacos,只要刷新微服務,就可以看到之前配置的規則。實現方式如下:

  1、在微服務中引入jar包

<! --Springcloud ailibaba sentinel-datasource-nacos做持久化用到-->
<dependency>
   <groupid>com.alibaba.csp</ groupId>
  <artifactId>sentinel-datasource-nacos</artifactId>
</dependency>

  2、yml配置文件中增加nacos數據源配置

spring:
   cloud:
      sentinel:
         transport:
             port:8719
          datasource:
               ds1:
                   nacos:
                      server-addr: localhost:8848
                      datald: ${spring.application.name}
                      groupld: DEFAULT_GROUP
                      data-type: json
                      rule-type: flow

  3、登錄nacos控制台配置流控規則:配置列表下新增配置,選json格式,填入如下json代碼

[ 
  {
    "resource":"/rateLimit/byUrl",
    "limitApp": "default",
    "grade": 1,
     "count": 1,
     "clusterMode": false
   }
]

  json中內容表示配規則,其中,resource表示資源名,limitApp表示來源應用,grade表示閾值類型-0線程數1QPS,count表示單機閾值,strategy表示流控模式-0直接1關聯2鏈路,controBehavior表示流控效果-0快速失敗1Warmup2排隊等待,clusterMode表示是否集群。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM