SpringCloudAlibaba-服務容錯Sentinel(進階)


一:基本概念

1.1 資源:就是Sentinel要保護的東西,它可以是Java應用程序中的任何內容,可以是一個服務,也可以是一個方法,甚至可以是一段代碼

1.2 規則:用來定義如何進行保護資源的

二:重要功能

Sentinel的主要功能就是容錯,主要體現在下面三個類型:

2.1 流量控制

流量控制在網絡傳輸中是一個常用的概念,它用於調整網絡包的數據。任意時間到來的請求往往是隨機不可控的,而系統的處理能力是有限的。我們需要根據系統的處理能力對流量進行控制。

2.2 熔斷降級

當檢測到調用鏈路中某個資源出現不穩定的表現,例如請求響應時間長或異常比例升高的時候,則對這個資源的調用進行限制,讓請求快速失敗,避免影響到其他的資源而導致級聯故障。

Sentinel對這個問題采取了兩種措施

1:通過並發線程數進行控制

Sentinel通過限制資源並發線程的數量,來減少不穩定資源對其他資源的影響。當某個資源出現不穩定的情況下,例如響應時間變長,對資源的直接影響就是會造成線程數的逐步堆積。當線程數

在特定資源上堆積到一定的數量之后,對該資源的新請求就會被拒絕。堆積的線程完成任務后才開始繼續接收請求。

2:通過響應時間對資源進行降級

當依賴的資源出現響應時間過長后,所有對該資源的訪問都會被直接拒絕,直到過了指定的時間窗口之后才重新恢復。

2.3 負載均衡保護

當系統負載均衡較高時,如果還持續讓請求進入可能會導致系統崩潰,無法響應。在集群環境下,會把本應這台機器承載的流量轉發到其他的機器上去。如果這個時候其他的機器也處在一個邊緣狀態的時候

Sentinel提供了對應的保護機制,讓系統的入口流量和系統的負載達到一個平衡,保證系統在能力范圍之內處理最多的請求。

三:Sentinel規則

3.1 流控規則

流量控制,其原理是監控應用流量的QPS或並發線程數等指標,當達到指定的閾值時對流量進行控制,以避免被瞬時的流量高峰沖垮,從而保障應用的高可用性。

第一步:點擊簇點鏈路,我們就可以看到訪問過的接口地址,然后點擊對應的流控按鈕,進入流控規則配置頁面。新增流控規則界面如下:

  

 

  • 資源名:唯一名稱,默認是請求路徑,可自定義
  • 針對來源:指定對哪個微服務進行限流,默認default,意思是不區分來源,全部限制
  • 閾值類型\單機閾值:
  • QPS(每秒請求數量):當調用接口的QPS達到閾值的時候,進行限流
  • 線程數:當調用接口的線程數達到閾值的時候,進行限流
  • 是否集群:本例不做集群

上一章文末簡單示例就是以QPS來配置的。

3.1.1 配置流控模式

點開高級選項  如下圖

  

 

可以看到有三種流控模式:直接、關聯、鏈路。接下來我們逐一演示

直接流控模式:最簡單的模式,當指定接口到達限流條件時開啟限流。參考上章案例

關聯流控模式:當指定接口關聯的接口達到限流條件時,開啟指定接口的限流。

第一步:配置限流規則,將流控模式設置為關聯,關聯資源設置為/sentinel/mesg2

  

 

第二步:通過jemeter訪問mesg2,達到限流狀態

  

 

第三步:訪問/sentinel/mesg1,會發現已經被限流

  

 

鏈路流控模式

當從某個接口過來的資源達到限流條件時,開啟限流。

配置流控效果

快速失敗(默認):直接失敗,拋出異常,不做任何額外的處理,是最簡單的效果

Warm up:它從開始閾值到最大QPS閾值會有一個緩沖階段,一開始的閾值是最大QPS閾值的1/3,然后慢慢增長,直到最大閾值,適用於將突然增大的流量轉換為緩步增長的場景。

排隊等待:讓請求以均勻的速度通過,單機閾值為每秒通過數量,其余的排隊等待; 它還會讓設置一個超時時間,當請求超過超時間時間還未處理,則會被丟棄。

3.2 降級規則:

當滿足什么條件的時候,對服務進行降級。Sentinel提供了三個衡量條件:

平均響應時間:當資源的平均響應時間超過閾值(以 ms 為單位)之后,資源進入准降級狀態。如果接下來 1s 內持續進入 5 個請求,它們的 RT都持續超過這個閾值,

            那么在接下的時間窗口(以 s 為單位)之內,就會對這個方法進行服務降級。

  

 

異常比例:當資源的每秒異常總數占通過量的比值超過閾值之后,資源進入降級狀態,即在接下來的時間窗口之內,對這個方法的調用都會自動返回。異常比例的閾值范圍是[0.0,1.0]

第一步:模擬異常

    int i = 0;
    @RequestMapping("/mesg2")
    public String message2(){
        i++;
        if(i%3 == 0){
            throw new RuntimeException();
        }
        return "message2";
    }

第二步:設置異常比例為0.25

  

3.3 熱點規則:

一種更細粒度的流控規則,它允許將規則具體到參數上。

第一步:代碼編寫

@RequestMapping("/mesg3")
@SentinelResource("mesg3")
public String message3(String name,Integer age){

return "message3="+name+"_"+age;
}

第二步:配置熱點規則

第三步:分別用兩個參數訪問,會發現只對第一個參數限流了

 熱點key增強使用:參數例外項允許對一個參數的具體值進行流控...(此處不做演示了)

3.4 授權規則:

來源訪問控制根據資源的請求來源限制資源 是否通過

若配置白名單,則只有請求來源定位於白名單內時才可通過;

若配置黑名單,則請求來源於黑名單時不通過,其余請求通過;

第一步:自定義來源處理規則

@Component
public class RequestOriginParserDefinition implements RequestOriginParser {
    @Override
    public String parseOrigin(HttpServletRequest request) {
        String serviceName = request.getParameter("serviceName");
        return serviceName;
    }
}

第二步:配置授權規則

這個配置的意思是只有serviceName=pc不能訪問(黑名單)

 

第三步:訪問接口查看效果

 

 3.5 系統規則

  系統保護規則是從應用級別的入口流量進行控制,從單台機器的總體 Load、RT、入口 QPS 、CPU使用率和線程數五個維度監控應用數據,讓系統盡可能跑在最大吞吐量的同時保證系統整體的穩定性。

系統保護規則是應用整體維度的,而不是資源維度的,並且僅對入口流量 (進入應用的流量) 生效。

  • Load(僅對 Linux/Unix-like 機器生效):當系統 load1 超過閾值,且系統當前的並發線程數超過系統容量時才會觸發系統保護。系統容量由系統的 maxQps * minRt 計算得出。設定參考值一般是 CPU cores * 2.5。
  • RT:當單台機器上所有入口流量的平均 RT 達到閾值即觸發系統保護,單位是毫秒。
  • 線程數:當單台機器上所有入口流量的並發線程數達到閾值即觸發系統保護。
  • 入口 QPS:當單台機器上所有入口流量的 QPS 達到閾值即觸發系統保護。
  • CPU使用率:當單台機器上所有入口流量的 CPU使用率達到閾值即觸發系統保護。

 四:Feign整合Sentinel

4.1 引入sentinel依賴

<!--sentinel組件-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>  

4.2  application.yml配置中開啟Feign對Sentinel的支持

# 開啟 Feign 對 Sentinel 的支持
feign:
  sentinel:
    enabled: true

4.3  創建容錯類

/**
 * 容錯類要求必須實現被容錯的接口,並為每個方法實現容錯方案
 */
@Component
@Slf4j
public class ProductApiFallback implements ProductApiService {
    @Override
    public Product getByPid(Integer pid) {
        Product product = new Product();
        product.setPname("服務容錯");
        product.setPid(-1);
        return product;
    }
}

4.4  對feign管理的接口指定容錯類

@FeignClient(value = "service-product",fallback = ProductApiFallback.class)//聲明調用的提供者的name
public interface ProductApiService {

    /**
     * 指定調用提供者的哪個方法
     * @FeignClient+@GetMapping 就是一個完整的請求路徑 http://service-product/product/{pid}
     * @param pid
     * @return
     */
    @GetMapping("/product/{pid}")
    Product getByPid(@PathVariable("pid") Integer pid);


}

4.5 停止或異常shop-product服務,請求接口測試

 


免責聲明!

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



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