溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

發(fā)布時(shí)間:2020-07-05 17:25:26 來(lái)源:網(wǎng)絡(luò) 閱讀:1897 作者:ZeroOne01 欄目:編程語(yǔ)言

常見(jiàn)容錯(cuò)方案

在微服務(wù)等分布式架構(gòu)中,服務(wù)容錯(cuò)是老生常談的問(wèn)題了,我們都知道在微服務(wù)架構(gòu)中會(huì)存在多個(gè)微服務(wù),而絕大部分微服務(wù)之間都會(huì)存在調(diào)用關(guān)系,若由于某個(gè)底層服務(wù)不可用從而產(chǎn)生連鎖反應(yīng),導(dǎo)致一系列的上層服務(wù)崩潰、故障,這種現(xiàn)象被稱為雪崩效應(yīng)或級(jí)聯(lián)故障。如下圖所示:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

所以在微服務(wù)等分布式架構(gòu)中,能夠防御服務(wù)雪崩效應(yīng)的容錯(cuò)方案是必不可少的,常見(jiàn)的容錯(cuò)方案如下:

1、超時(shí):

設(shè)置請(qǐng)求超時(shí)時(shí)間,讓請(qǐng)求線程在等待超過(guò)一定的時(shí)間后就判定為請(qǐng)求失敗從而釋放請(qǐng)求線程,在某些場(chǎng)景下線程釋放得夠快的話,就不會(huì)因?yàn)椴粩鄤?chuàng)建線程而導(dǎo)致資源耗盡引起的服務(wù)崩潰

2、限流:

例如,上圖中的服務(wù)A只能承受1k左右的QPS,那么就設(shè)置一個(gè)最大請(qǐng)求數(shù)量閾值,當(dāng)QPS達(dá)到1k時(shí)就拒絕在這之后的請(qǐng)求。就像是我只能吃一碗飯,就算給我三碗我也只吃一碗

3、艙壁模式:

艙壁模式實(shí)際上就是借鑒于現(xiàn)實(shí)生活中的船艙結(jié)構(gòu)而設(shè)計(jì),一艘船想要不那么容易沉也需要具備有一定的”容錯(cuò)“能力,而早期的船由于設(shè)計(jì)上的欠缺,只要一個(gè)地方進(jìn)水了,那么水就會(huì)逐漸漫進(jìn)整個(gè)船艙,這種結(jié)構(gòu)的船幾乎沒(méi)有“容錯(cuò)”能力,所以就比較容易沉。于是此時(shí)就有人想到將原本一體的船艙分隔成一個(gè)個(gè)獨(dú)立的船艙,船艙之間都使用鋼板焊死隔開(kāi),這些鋼板就是所謂的艙壁了。采用這種設(shè)計(jì)后,就算當(dāng)其中一個(gè)兩個(gè)船艙進(jìn)水了,也不會(huì)影響到其他船艙,這艘船依舊能夠正常行駛。

在軟件層面上借鑒這種思想,我們可以讓每個(gè)服務(wù)都運(yùn)行在自己獨(dú)立的線程池中,線程池之間是互不干擾的,服務(wù)A的線程池資源耗盡也不會(huì)影響到服務(wù)B。此時(shí)線程池就像船艙的艙壁一樣將不同的服務(wù)資源隔離開(kāi)來(lái),這樣某個(gè)服務(wù)掛掉也不會(huì)影響其他服務(wù)的運(yùn)行

4、斷路器模式:

斷路器模式的思想實(shí)際上和家里的斷路器一樣,在軟件層面大致就是對(duì)某個(gè)服務(wù)的API進(jìn)行監(jiān)控,若在一定時(shí)間內(nèi)調(diào)用的失敗率或失敗次數(shù)達(dá)到指定的閾值就認(rèn)為該API是不可用的從而觸發(fā)“跳閘”,即此時(shí)斷路器就處于打開(kāi)狀態(tài)。過(guò)了一段時(shí)間后斷路器會(huì)處于一個(gè)半開(kāi)狀態(tài),若在半開(kāi)狀態(tài)時(shí)嘗試調(diào)用該API成功后就會(huì)關(guān)閉斷路器,否則依舊認(rèn)為不可用讓斷路器繼續(xù)處于打開(kāi)狀態(tài)

斷路器三態(tài)轉(zhuǎn)換如下圖:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

斷路器模式原文:CircuitBreaker

而Spring Cloud已經(jīng)提供了相關(guān)的服務(wù)容錯(cuò)組件,組件里已經(jīng)整合了這些常用的方案,不需要我們手動(dòng)去實(shí)現(xiàn)。在此之前Spring Cloud提供的唯一服務(wù)容錯(cuò)組件是Hystrix,不過(guò)現(xiàn)在多了一個(gè)選擇,那就是Spring Cloud Alibaba的Sentinel組件。關(guān)于Hystrix可以參考如下文章,本文主要介紹Sentinel:

  • Spring Cloud Hystrix - 服務(wù)容錯(cuò)

Sentinel簡(jiǎn)介及整合

Sentinel 是什么,官方描述如下:

隨著微服務(wù)的流行,服務(wù)和服務(wù)之間的穩(wěn)定性變得越來(lái)越重要。Sentinel 是面向分布式服務(wù)架構(gòu)的輕量級(jí)流量控制、熔斷降級(jí)框架,主要以流量為切入點(diǎn),從流量控制、熔斷降級(jí)、系統(tǒng)負(fù)載保護(hù)等多個(gè)維度來(lái)幫助您保護(hù)服務(wù)的穩(wěn)定性。

官方GitHub倉(cāng)庫(kù)地址如下:

https://github.com/alibaba/Sentinel

現(xiàn)在我們來(lái)為項(xiàng)目整合Sentinel,第一步添加如下依賴:

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- actuator,用于暴露監(jiān)控端點(diǎn) -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>

Tips:該項(xiàng)目使用的Spring Cloud版本為Greenwich.SR1,Spring Cloud Alibaba版本為0.9.0.RELEASE

第二步配置actuator:

# 暴露所有端點(diǎn)
management:
  endpoints:
    web:
      exposure:
        include: '*'

完成以上兩步后,啟動(dòng)項(xiàng)目,使用瀏覽器訪問(wèn)http://localhost:8080/actuator/sentinel,返回如下結(jié)果代表整合成功:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]


搭建Sentinel Dashboard控制臺(tái)

在上一小節(jié)中,我們已經(jīng)為項(xiàng)目成功整合了Sentinel,但這也只不過(guò)是完成了第一步。因?yàn)榇藭r(shí)沒(méi)有一個(gè)可視化的界面能讓我們看到Sentinel具體的監(jiān)控信息,所以還需要搭建官方提供的可視化Sentinel控制臺(tái),然后在控制臺(tái)中整合項(xiàng)目的監(jiān)控信息。

Sentinel控制臺(tái)的下載地址如下:

https://github.com/alibaba/Sentinel/releases

Sentinel Dashboard有多個(gè)release版本,應(yīng)該選擇哪個(gè)呢?如果你是用在生產(chǎn)環(huán)境則選擇與項(xiàng)目中sentinel-core版本對(duì)應(yīng)的即可,如下:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

若只是學(xué)習(xí)或測(cè)試使用那就可以隨便選擇了,只要能用就行,所以我這里選擇最新版本1.6.3,注意這里選擇jar包進(jìn)行下載:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

下載完成后,存放到一個(gè)你覺(jué)得ok的目錄下,然后打開(kāi)cmd,通過(guò)命令運(yùn)行該jar包。如下:

E:\Spring Cloud Alibaba\Sentinel>java -jar sentinel-dashboard-1.6.3.jar

啟動(dòng)成功,監(jiān)聽(tīng)的端口是8080:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

使用瀏覽器訪問(wèn)http://localhost:8080進(jìn)入到登錄頁(yè)面,默認(rèn)的賬戶密碼都是sentinel:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

登錄成功,此時(shí)控制臺(tái)上是空白的,因?yàn)檫€沒(méi)有監(jiān)控任何的項(xiàng)目:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

所以接著到項(xiàng)目中整合一下Sentinel Dashboard的請(qǐng)求地址,在配置文件中添加如下配置:

spring:
  cloud:
    sentinel:
      transport:
        # 配置sentinel控制臺(tái)的地址
        dashboard: 127.0.0.1:8080

配置完成啟動(dòng)項(xiàng)目后需要先訪問(wèn)一下該項(xiàng)目的接口,因?yàn)镾entinel Dashboard是懶加載的,只有監(jiān)控的項(xiàng)目被訪問(wèn)后才會(huì)收集監(jiān)控信息。這樣才能看到下圖的實(shí)時(shí)監(jiān)控信息,我這里的服務(wù)名是content-center:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]


Sentinel 相關(guān)配置項(xiàng)小結(jié)

客戶端(微服務(wù))連接控制臺(tái)相關(guān)配置項(xiàng):

spring:
  cloud:
    sentinel:
      transport:
        #指定控制臺(tái)的地址
        dashboard: localhost:8080
        #指定和控制臺(tái)通信的IP
        #如不配置,會(huì)自動(dòng)選擇一個(gè)IP注冊(cè)
        client-ip:  127.0.0.1
        #指定和控制臺(tái)通信的端口,默認(rèn)值8719
        #如不設(shè)置,會(huì)自動(dòng)從8719開(kāi)始掃描,依次+1,直到找到未被占用的端口
        port: 8719
        #心跳發(fā)送周期,默認(rèn)值null
        #但在S impleHttpHeartbeatSender會(huì)用默認(rèn)值10秒
        heartbeat- interval-ms :  10000

控制臺(tái)相關(guān)配置項(xiàng):

配置項(xiàng) 默認(rèn)值 最小值 描述
sentinel.dashboard.app.hideAppNoMachineMillis 0 60000 是否隱藏?zé)o健康節(jié)點(diǎn)的應(yīng)用,距離最近一次主機(jī)心跳時(shí)間的毫秒數(shù),默認(rèn)關(guān)閉
sentinel.dashboard.removeAppNoMachineMillis 0 120000 是否自動(dòng)刪除無(wú)健康節(jié)點(diǎn)的應(yīng)用,距離最近一次其下節(jié)點(diǎn)的心跳時(shí)間毫秒數(shù),默認(rèn)關(guān)閉
sentinel.dashboard.unhealthyMachineMillis 60000 30000 主機(jī)失聯(lián)判定,不可關(guān)閉
sentinel.dashboard.autoRemoveMachineMillis 0 300000 距離最近心跳時(shí)間超過(guò)指定時(shí)間是否自動(dòng)刪除失聯(lián)節(jié)點(diǎn),默認(rèn)關(guān)閉
server.port 8080 - 指定端口
csp.sentinel.dashboard.server localhost:8080 - 指定地址
project.name - - 指定程序的名稱
sentinel.dashboard.auth.username [1.6版本支持] sentinel - Sentinel Dashboard登錄賬號(hào)
sentinel.dashboard.auth.password [1.6版本支持] sentinel - Sentinel Dashboard登錄密碼
server.servlet.session.timeout [1.6版本支持] 30分鐘 - 登錄Session過(guò)期時(shí)間。配置為7200表示7200秒;配置為60m表示60分鐘

控制臺(tái)配置項(xiàng)需在啟動(dòng)命令中指定,例如指定賬戶密碼,如下:

java -jar -Dsentinel.dashboard.auth.username=admin -Dsentinel.dashboard.auth.password=123456 sentinel-dashboard-1.6.3.jar

流控規(guī)則

我們可以在Sentinel控制臺(tái)中給某個(gè)接口添加流控規(guī)則,點(diǎn)擊簇點(diǎn)鏈路,可以看到該服務(wù)曾經(jīng)被訪問(wèn)過(guò)的路徑:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

然后點(diǎn)擊接口右邊的流控按鈕就可以添加流控規(guī)則:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

添加成功:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

此時(shí)訪問(wèn)該服務(wù)的接口,QPS超過(guò)設(shè)定的閾值1,就會(huì)返回如下信息:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]


關(guān)于流控規(guī)則中的流控模式:

  • 直接:當(dāng)前資源的QPS達(dá)到設(shè)定的閾值,就觸發(fā)限流
  • 關(guān)聯(lián):當(dāng)關(guān)聯(lián)的資源的QPS達(dá)到設(shè)定的閾值,就觸發(fā)限流。例如,/shares/1關(guān)聯(lián)了/query,那么/query達(dá)到閾值,就會(huì)對(duì)/shares/1限流
  • 鏈路:只記錄指定鏈路上的流量,這種模式是針對(duì)接口級(jí)別的來(lái)源進(jìn)行限流

鏈路模式稍微有些抽象,這里舉個(gè)簡(jiǎn)單的例子說(shuō)明一下。下圖中有兩個(gè)調(diào)用鏈路,圖中的/test-b/test-a實(shí)際就是兩個(gè)接口,它們都調(diào)用了同一個(gè)common資源,所以/test-b/test-a就稱為common的入口資源:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

此時(shí)我為common添加一個(gè)限流規(guī)則如下:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

可以看到流控模式選擇鏈路后,需要填寫(xiě)一個(gè)入口資源,我這里填的是/test-a,那么這意味著什么呢?意味著當(dāng)/test-a的QPS達(dá)到該規(guī)則的閾值后,就會(huì)對(duì)/test-a限流,同時(shí)/test-b不會(huì)受到任何影響。說(shuō)明這種流控模式可以針對(duì)接口級(jí)別的來(lái)源進(jìn)行限流,而“針對(duì)來(lái)源”則是對(duì)微服務(wù)級(jí)別的來(lái)源進(jìn)行限流。

關(guān)于流控規(guī)則中的監(jiān)控效果:

  • 快速失敗:直接失敗,拋出異常,不做任何額外的處理,是最簡(jiǎn)單的效果
    • 相關(guān)源碼:com.alibaba.csp.sentinel.slots.block.flow.controller.DefaultController
  • Warm Up(預(yù)熱):會(huì)根據(jù)codeFactor(默認(rèn)3)的值,從閾值除以codeFactor,經(jīng)過(guò)預(yù)熱時(shí)長(zhǎng),才到達(dá)設(shè)置的QPS閾值。適用于將突然增大的流量轉(zhuǎn)換為緩步增長(zhǎng)的場(chǎng)景
    • 相關(guān)的官方文檔:限流 - 冷啟動(dòng)
    • 相關(guān)源碼:com.alibaba.csp.sentinel.slots.block.flow.controller.WarmUpController
  • 排隊(duì)等待:勻速排隊(duì),讓請(qǐng)求以均勻的速度通過(guò),若請(qǐng)求等待時(shí)間超過(guò)設(shè)置的超時(shí)時(shí)間則拋棄該請(qǐng)求,閾值類(lèi)型必須設(shè)置成QPS,否則無(wú)效。適用于突發(fā)流量的場(chǎng)景
    • 相關(guān)的官方文檔:限流 - 勻速器
    • 相關(guān)源碼:com.alibaba.csp.sentinel.slots.block.flow.controller.RateLimiterController

關(guān)于流控的官方文檔:

  • 流量控制

降級(jí)規(guī)則

服務(wù)降級(jí)實(shí)際就是斷路器模式的應(yīng)用,相對(duì)于流控規(guī)則,降級(jí)規(guī)則要簡(jiǎn)單一些。降級(jí)規(guī)則可以在“簇點(diǎn)鏈路”或“降級(jí)規(guī)則”中添加:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

例如,這里給/shares/1添加降級(jí)規(guī)則,降級(jí)策略先以RT為例:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

該降級(jí)規(guī)則的含義如下圖:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

此時(shí)訪問(wèn)/shares/1接口,秒級(jí)平均響應(yīng)時(shí)間超出閾值1,并且在時(shí)間窗口內(nèi)通過(guò)的請(qǐng)求大于等于5,就會(huì)返回如下信息:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

關(guān)于RT這種降級(jí)策略需要注意的點(diǎn):

  • RT默認(rèn)最大為4900ms,所以即便設(shè)置的值大于4900ms也依舊會(huì)按照4900ms計(jì)算
    • 可以通過(guò)參數(shù)修改:-Dcsp.sentinel.statistic.max.rt=xxx

若將降級(jí)策略改為異常比例,則含義如下:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

若將降級(jí)策略改為異常數(shù),則含義如下:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

關(guān)于異常數(shù)這種降級(jí)策略需要注意的點(diǎn):

  • 若將時(shí)間窗口的值設(shè)置小于60秒則可能會(huì)出問(wèn)題,因?yàn)楫惓?shù)的統(tǒng)計(jì)是分鐘級(jí)別的,時(shí)間窗口小于60秒就有可能不斷進(jìn)入降級(jí)狀態(tài)

降級(jí)規(guī)則的相關(guān)源碼:

  • com.alibaba.csp.sentinel.slots.block.degradeDegradeRule#passCheck(對(duì)降級(jí)的判斷都在這個(gè)方法里完成)

在文章的開(kāi)頭我們介紹過(guò)斷路器有三個(gè)狀態(tài),所以這里需要提及一下的是目前Sentinel的降級(jí)斷路器是不支持半開(kāi)狀態(tài)的,只有打開(kāi)和關(guān)閉兩個(gè)狀態(tài),據(jù)官方人員描述說(shuō)是會(huì)預(yù)計(jì)在未來(lái)添加半開(kāi)的支持。

關(guān)于降級(jí)的官方文檔:

  • 熔斷降級(jí)

熱點(diǎn)規(guī)則

熱點(diǎn)規(guī)則全稱是熱點(diǎn)參數(shù)限流規(guī)則,從名稱可以得知,需要有參數(shù)的接口才能夠使用熱點(diǎn)規(guī)則。例如,有一個(gè)接口的代碼如下:

@GetMapping("/test-hot")
@SentinelResource("hot")  // 該注解用于聲明是Sentinel需要監(jiān)控的資源
public String testHot(@RequestParam(required = false) String a,
                      @RequestParam(required = false) String b) {
    return a + " " + b;
}

在控制臺(tái)中為hot添加熱點(diǎn)規(guī)則,如下:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

  • Tips:參數(shù)索引從0開(kāi)始,對(duì)應(yīng)到代碼中的話,則參數(shù)a的索引為0,參數(shù)b的索引為1,所以該規(guī)則是作用于參數(shù)a

添加完該規(guī)則后,此時(shí)訪問(wèn)這個(gè)接口,兩個(gè)參數(shù)都傳值,當(dāng)QPS達(dá)到閾值時(shí),就會(huì)拋出如下異常信息:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

如果不傳參數(shù)a,僅傳參數(shù)b的話,則不會(huì)受到該規(guī)則的限流,如下:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

說(shuō)明該規(guī)則表達(dá)的含義是:在時(shí)間窗口內(nèi),一旦該規(guī)則指定的索引參數(shù)QPS達(dá)到了閾值,則會(huì)觸發(fā)限流

除此之外,還有高級(jí)選項(xiàng),在這里可以添加參數(shù)例外項(xiàng),如下示例:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

添加完成后,此時(shí)將參數(shù)a的值設(shè)置為5,然后頻繁發(fā)送請(qǐng)求,會(huì)發(fā)現(xiàn)即便QPS超過(guò)1也不會(huì)觸發(fā)限流:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

這是因?yàn)閰?shù)a的值設(shè)置為5時(shí),限流閾值是1000,設(shè)置為其他值時(shí),限流閾值才是1。這就是所謂的參數(shù)例外項(xiàng)了,即參數(shù)的為某個(gè)特定的值時(shí),只受參數(shù)例外項(xiàng)里的限流閾值影響。

熱點(diǎn)規(guī)則適用的場(chǎng)景:

  • 適用于存在熱點(diǎn)參數(shù)并希望提升API可用性的場(chǎng)景,即某個(gè)特定請(qǐng)求參數(shù)QPS偏高于其他請(qǐng)求參數(shù)時(shí),僅對(duì)該參數(shù)的請(qǐng)求限流,使用其他請(qǐng)求參數(shù)則可以正常響應(yīng),這樣可以提高一定的可用性

使用熱點(diǎn)規(guī)則需要注意的點(diǎn):

  • 參數(shù)必須是基本類(lèi)型或者String類(lèi)型,否則將不會(huì)生效

熱點(diǎn)規(guī)則相關(guān)源碼:

  • com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowChecker#passCheck(對(duì)熱點(diǎn)參數(shù)規(guī)則的判斷邏輯都在這個(gè)方法里)

系統(tǒng)規(guī)則

系統(tǒng)規(guī)則全稱為系統(tǒng)保護(hù)規(guī)則,從名稱可以得知該規(guī)則是用于保護(hù)系統(tǒng)、防止系統(tǒng)負(fù)載過(guò)高而崩潰的,所以觸發(fā)系統(tǒng)規(guī)則后會(huì)對(duì)整個(gè)系統(tǒng)限流。添加系統(tǒng)規(guī)則如下圖所示:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

設(shè)置系統(tǒng)規(guī)則比較簡(jiǎn)單,選擇一個(gè)合適的閾值類(lèi)型并填寫(xiě)閾值即可:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

關(guān)于閾值類(lèi)型:

  • LOAD(負(fù)載):當(dāng)系統(tǒng)load1(1分鐘的load)超過(guò)閾值,且并發(fā)線程數(shù)超過(guò)系統(tǒng)容量時(shí)觸發(fā),建議設(shè)置為CPU核心數(shù) 2.5(注意:僅對(duì) Linux/Unit-like 機(jī)器生效)。例如CPU核心數(shù)為4,`4 2.5 = 10`
    • 系統(tǒng)容量 = maxQPS * minRT;(由Sentinel計(jì)算 )
      • maxQPS:秒級(jí)統(tǒng)計(jì)出來(lái)的最大QPS
      • minRT:秒級(jí)統(tǒng)計(jì)出來(lái)的最小響應(yīng)時(shí)間
    • 相關(guān)源碼:com.alibaba.csp.sentinel.slots.system.SystemRuleManager#checkBbr
  • RT:所有入口流量的平均RT達(dá)到閾值時(shí)觸發(fā)
  • 線程數(shù):所有入口流量的并發(fā)線程數(shù)達(dá)到閾值時(shí)觸發(fā)
  • 入口QPS:所有入口流量的QPS達(dá)到閾值時(shí)觸發(fā)
  • CPU使用率:系統(tǒng)CPU使用率達(dá)到閾值時(shí)觸發(fā)

系統(tǒng)規(guī)則的判斷邏輯所在的源碼如下:

  • com.alibaba.csp.sentinel.slots.system.SystemRuleManager#checkSystem

授權(quán)規(guī)則

授權(quán)規(guī)則用于限制某個(gè)資源僅允許哪個(gè)服務(wù)訪問(wèn),所以通常用于對(duì)服務(wù)消費(fèi)者的訪問(wèn)權(quán)進(jìn)行控制。我們可以在簇點(diǎn)鏈路中為某個(gè)接口添加授權(quán)規(guī)則,這里以/shares/1接口為例,如下:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

新增授權(quán)規(guī)則:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

  • 該授權(quán)規(guī)則的含義為:僅允許test服務(wù)訪問(wèn)/shares/1接口,如果授權(quán)類(lèi)型設(shè)置為黑名單則表示/shares/1接口不允許test服務(wù)訪問(wèn)。即白名單是授權(quán)某個(gè)服務(wù)訪問(wèn),黑名單則是限制某個(gè)服務(wù)訪問(wèn),從而實(shí)現(xiàn)訪問(wèn)控制的效果。

代碼配置規(guī)則

上面幾個(gè)關(guān)于規(guī)則的小節(jié)中已經(jīng)介紹了如何在Sentinel控制臺(tái)中配置各種規(guī)則,除此之外,Sentinel還支持在代碼中配置這些規(guī)則,所以本小節(jié)將簡(jiǎn)單介紹一下如何在代碼中進(jìn)行配置。

代碼如下(Tips:代碼基于sentinel-core 1.5.2版本):

package com.zj.node.contentcenter.controller.content;

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRule;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowItem;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.csp.sentinel.slots.system.SystemRule;
import com.alibaba.csp.sentinel.slots.system.SystemRuleManager;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * 添加Sentinel規(guī)則
 *
 * @author 01
 * @date 2019-07-31
 **/
@Slf4j
@RestController
public class SentinelRuleController {

    /**
     * 測(cè)試添加流控規(guī)則
     */
    @PostMapping("/test-add-flow-rule")
    public String testAddFlowRile(String resourceName) {
        log.info("add flow rule. resourceName is {}", resourceName);
        addFlowQpsRule(resourceName);

        return "add flow rule success!";
    }

    /**
     * 添加流控規(guī)則
     *
     * @param resourceName 資源名稱
     */
    private void addFlowQpsRule(String resourceName) {
        // 規(guī)則列表
        List<FlowRule> rules = new ArrayList<>();
        FlowRule rule = new FlowRule(resourceName);
        // 針對(duì)來(lái)源
        rule.setLimitApp("default");
        // 設(shè)置閾值類(lèi)型為QPS
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // 單機(jī)閾值
        rule.setCount(20);
        // 將規(guī)則添加到規(guī)則列表
        rules.add(rule);
        // 加載規(guī)則列表
        FlowRuleManager.loadRules(rules);
    }

    /**
     * 添加降級(jí)規(guī)則
     *
     * @param resourceName 資源名稱
     */
    private void addDegradeRule(String resourceName) {
        List<DegradeRule> rules = new ArrayList<>();
        DegradeRule rule = new DegradeRule(resourceName);
        // 設(shè)置降級(jí)策略為 RT
        rule.setGrade(RuleConstant.DEGRADE_GRADE_RT);
        // set threshold RT, 10 ms(設(shè)置RT時(shí)間閾值)
        rule.setCount(10);
        // 時(shí)間窗口
        rule.setTimeWindow(10);
        rules.add(rule);
        DegradeRuleManager.loadRules(rules);
    }

    /**
     * 添加熱點(diǎn)規(guī)則
     *
     * @param resourceName 資源名稱
     */
    private void addHotRule(String resourceName) {
        ParamFlowRule rule = new ParamFlowRule(resourceName);
        // 參數(shù)索引
        rule.setParamIdx(0);
        // 單機(jī)閾值
        rule.setCount(5);

        // 添加參數(shù)例外項(xiàng)
        ParamFlowItem item = new ParamFlowItem();
        // 參數(shù)類(lèi)型
        item.setClassType(int.class.getName());
        // 參數(shù)值
        item.setObject("5");
        // 限流閾值
        item.setCount(10);
        rule.setParamFlowItemList(Collections.singletonList(item));

        ParamFlowRuleManager.loadRules(Collections.singletonList(rule));
    }

    /**
     * 添加系統(tǒng)規(guī)則
     */
    private void addSystemRule() {
        List<SystemRule> rules = new ArrayList<>();
        SystemRule rule = new SystemRule();
        // 設(shè)置系統(tǒng)最高負(fù)載閾值
        rule.setHighestSystemLoad(10);
        rules.add(rule);
        SystemRuleManager.loadRules(rules);
    }

    /**
     * 添加授權(quán)規(guī)則
     *
     * @param resourceName 資源名稱
     * @param limitApp     流控應(yīng)用(指調(diào)用方,多個(gè)調(diào)用方名稱使用英文逗號(hào)分隔)
     */
    private void addAuthorityRule(String resourceName, String limitApp) {
        AuthorityRule rule = new AuthorityRule();
        // 資源名稱
        rule.setResource(resourceName);
        // 流控應(yīng)用
        rule.setLimitApp(limitApp);
        // 設(shè)置授權(quán)類(lèi)型為白名單
        rule.setStrategy(RuleConstant.AUTHORITY_WHITE);

        AuthorityRuleManager.loadRules(Collections.singletonList(rule));
    }
}

我們來(lái)測(cè)試添加流控規(guī)則,使用postman訪問(wèn)測(cè)試接口,如下:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

添加成功后,到Sentinel控制臺(tái)中,查看是否存在該規(guī)則:
Spring Cloud Alibaba之服務(wù)容錯(cuò)組件 - Sentinel [基礎(chǔ)篇]

從上圖中可以看到該流控規(guī)則已經(jīng)成功添加到Sentinel中了,證明測(cè)試成功。至于其他的規(guī)則也可以使用類(lèi)似的方式添加,并且也都給出了代碼,這里就不一一去演示了。


Sentinel規(guī)則參數(shù)總結(jié)

下面總結(jié)一下Alibaba Sentinel各種規(guī)則的參數(shù),并且提供了官方文檔的鏈接,若未來(lái)本文不再適用,可以自行點(diǎn)擊鏈接前往官方文檔查看

1、流控規(guī)則:

Field 說(shuō)明 默認(rèn)值
resource 資源名,資源名是限流規(guī)則的作用對(duì)象 無(wú)
count 限流閾值 無(wú)
grade 限流閾值類(lèi)型,QPS 或線程數(shù)模式 QPS 模式
limitApp 流控針對(duì)的調(diào)用來(lái)源 default,代表不區(qū)分調(diào)用來(lái)源
strategy 判斷的根據(jù)是資源自身,還是根據(jù)其它關(guān)聯(lián)資源 (refResource),還是根據(jù)鏈路入口 根據(jù)資源本身
controlBehavior 流控效果(直接拒絕 / 排隊(duì)等待 / 慢啟動(dòng)模式) 直接拒絕

官方文檔:

  • 流量控制
  • 如何使用#流量控制規(guī)則-flowrule

2、降級(jí)規(guī)則:

Field 說(shuō)明 默認(rèn)值
resource 資源名,即限流規(guī)則的作用對(duì)象 無(wú)
count 閾值 無(wú)
grade 降級(jí)模式,根據(jù) RT 降級(jí)還是根據(jù)異常比例或異常數(shù)降級(jí) RT
timeWindow 降級(jí)的時(shí)間,單位為 s 無(wú)

官方文檔:

  • 如何使用#熔斷降級(jí)規(guī)則-degraderule
  • 熔斷降級(jí)

3、熱點(diǎn)規(guī)則:

Field 說(shuō)明 默認(rèn)值
resource 資源名,即熱點(diǎn)規(guī)則的作用對(duì)象 無(wú)
count 限流閾值,必填 無(wú)
grade 限流模式 QPS 模式
durationInSec 統(tǒng)計(jì)窗口時(shí)間長(zhǎng)度(單位為秒),1.6.0 版本開(kāi)始支持 1s
controlBehavior 流控效果(支持快速失敗和勻速排隊(duì)模式),1.6.0 版本開(kāi)始支持 快速失敗
maxQueueingTimeMs 最大排隊(duì)等待時(shí)長(zhǎng)(僅在勻速排隊(duì)模式生效),1.6.0 版本開(kāi)始支持 0ms
paramIdx 熱點(diǎn)參數(shù)的索引,必填,對(duì)應(yīng) SphU.entry(xxx, args) 中的參數(shù)索引位置 無(wú)
paramFlowItemList 參數(shù)例外項(xiàng),可以針對(duì)指定的參數(shù)值單獨(dú)設(shè)置限流閾值,不受前面 count 閾值的限制。僅支持基本類(lèi)型和字符串類(lèi)型 無(wú)
clusterMode 是否是集群參數(shù)流控規(guī)則 false
clusterConfig 集群流控相關(guān)配置 無(wú)

官方文檔:

  • 熱點(diǎn)參數(shù)限流#熱點(diǎn)參數(shù)規(guī)則

4、系統(tǒng)規(guī)則:

Field 說(shuō)明 默認(rèn)值
highestSystemLoad 最大的 load1,參考值 -1 (不生效)
avgRt 所有入口流量的平均響應(yīng)時(shí)間 -1 (不生效)
maxThread 入口流量的最大并發(fā)數(shù) -1 (不生效)
qps 所有入口資源的 QPS -1 (不生效)

官方文檔:

  • 如何使用#系統(tǒng)保護(hù)規(guī)則-systemrule
  • 系統(tǒng)自適應(yīng)限流

5、授權(quán)規(guī)則:

Field 說(shuō)明 默認(rèn)值
resource 資源名,即授權(quán)規(guī)則的作用對(duì)象 無(wú)
limitApp 流控應(yīng)用(指調(diào)用方,即服務(wù)消費(fèi)者),對(duì)應(yīng)的黑名單/白名單,不同 origin 用英文逗號(hào)(,)分隔,如 appA,appB 無(wú)
strategy 限制模式,AUTHORITY_WHITE 為白名單模式,AUTHORITY_BLACK 為黑名單模式,默認(rèn)為白名單模式 AUTHORITY_WHITE

官方文檔:

  • 如何使用#訪問(wèn)控制規(guī)則-authorityrule
  • 黑白名單控制
向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI