主頁 > 後端開發 > Spring Cloud Alibaba組件之Sentinel

Spring Cloud Alibaba組件之Sentinel

2023-01-05 07:04:27 後端開發

目錄

一 引入Sentinel學習

二 Sentinel入門

三 搭建Sentinel Dashboard

四 Springboot專案接入Sentinel

五 接入限流埋點

六 限流配置

七 熔斷降級

八 熔斷降級Spring Cloud示例

九 黑白名單(授權規則) 

十 持久化

十一 Spring Cloud Alibaba Sentinel三種保護應用方式

一 引入Sentinel學習

提起Spring Cloud的限流降級組件,一般首先想到的是Netflix的Hystrix,

不過就在2018年底,Netflix宣布不再積極開發Hystrix,該專案將處于維護模式,官方表示1.5.18 版本的Hystrix已經足夠穩定,可以滿足Netflix 現有應用的需求,所以接下來其會把焦點轉向對于自適應的實作,更多關注對應用程式的實時性能做出回應,對于新應用的熔斷需求,將采用其它專案實作,Netflix推薦了Resilience4j,

作為Spring Cloud Netflix重要套件,Hystrix已經成為保障微服務穩定性的首選應用,其實除了Netflix和Resilience4j,限流降級還有一個新的選擇,就是阿里巴巴的Sentinel組件,

二 Sentinel入門

官方檔案:https://sentinelguard.io/zh-cn/docs/introduction.html

1 什么是Sentinel?

1.1 問題:

隨著微服務的流行,服務與服務之間的呼叫穩定性變得越來越重要;

1、當服務訪問量達到一定程度,流量扛不住的時候,該如何處理?(限流)

2、服務之間相互依賴,當服務B出現回應時間過長,影響到服務A的回應(A呼叫B),進而產生連鎖反應,直至影響整個依賴鏈上的所有服務(雪崩),該如何處理?(熔斷降級)

 這是分布式、微服務開發不可避免的問題,

1.2 Sentinel是什么?

Sentinel(分布式系統的流量防衛兵)是阿里開源的一套用于服務容錯的綜合性解決方案,隨著微服務的流行,服務和服務之間的穩定性變得越來越重要,它以流量為切入點,從流量控制,熔斷降級,系統負載保護等多個維度來保護服務的穩定性,

2 Sentinel的特征

1、豐富的應用場景:Sentinel承接了阿里巴巴近10年的雙十一大促流量的核心場景,例如秒殺(即突發流量控制在系統容量可以承受的范圍),訊息削峰填谷,集群流量控制,實時熔斷下游不可用應用等,

2、完備的實時監控:Sentinel提供了實時的監控功能,通過控制可以看到接入應用的單臺機器秒級資料,甚至500臺以下規模的集群的匯總運行情況,

3、廣泛的開源生態:Sentinel提供開箱即用的與其他開源框架/庫的整合模塊,例如與SpringCLoud,Dubbo,gRPC的整合,只需要進入相應的依賴并進行簡單的配置即可快速地接入Sentinel,

4、完善的SPI擴展點:Sentinel提供簡單易用,完善的SPI擴展介面,您可以通過實作擴展介面來快速地定制邏輯,例如定制規則管理,適配動態資料源等,

3 Sentinel組成

Sentinel分為兩個部分,具體如下:

1、核心庫(Java客戶端):不依賴任何框架/庫,能夠運行于所有Java運行時環境,同時對Dubbo/Spring Cloud等框架也有比較好的支持(你的微服務程式,可以直接添加sentinel.jar包),

2、控制臺(Dashboard)基于Spring Boot開發,打包后可以直接運行,不需要額外的Tomcat等應用容器(因為控制臺是使用springboot開發,springboot內嵌了tomcat容器),

這里我們先學習一下控制臺的使用方式,

三 搭建Sentinel Dashboard

將應用接入Sentinel,最好搭建Sentinel控制臺,可以在控制臺上配置規則,

Dashboard是Alibaba寫好的SpringBoot程式,我們直接下載啟動即可.

1 下載Sentinel Dashboard

下載地址:https://github.com/alibaba/Sentinel/releases

 

2 啟動控制臺

我們可以在Linux系統或者Windows系統啟動Sentinel控制臺,這里是直接在Windows上啟動

#直接使用jar命令啟動專案(控制臺本身是一個SpringBoot專案)
java -Dserver.port=9090 -jar sentinel-dashboard-1.8.5.jar
其中,-Dserver.port=9090 代表控制臺專案的埠號

3 訪問控制臺

啟動Sentinel Dashboard通過地址和埠號控制臺

http://localhost:9090/#/login
#如果在Linux上啟動,ip需要對應上

輸入默認用戶名和密碼(sentinel/sentinel),之后控制臺可以看到sentinel-dashboard監控的指標,

如果要自定義用戶名和密碼,在啟動命令加上設定用戶名和密碼引數即可,如下:

-Dsentinel.dashboard.auth.username=admin -Dsentinel.dashboard.auth.password=123456

注意:默認啟動后,控制臺上沒有任何服務被注冊到控制臺,在啟動控制臺時,可以通過引數設定將控制臺本身注冊到控制臺上

-Dcsp.sentinel.dashboard.server=localhost:9090
-Dproject.name=sentinel-dashboard
# 其中:
# -Dcsp.sentinel.dashboard.server=localhost:9090 代表本控制臺服務將會注冊到自己的控制臺
# -Dproject.name=sentinel-dashboard 代表本控制臺服務的專案名稱,

我們可以看到控制臺自身的服務已經注冊到了控制臺上,

默認情況下,Sentinel Dashboard 中的增加的配置規則是存盤在記憶體中,重啟后就會丟失;

Sentinel 會在客戶端首次呼叫的時候進行初始化,開始向控制臺發送心跳包,所以要確保客戶端有訪問量;

Sentinel Dashboard是一個獨立的web應用(springboot開發的),可以接受客戶端(微服務)的連接,然后與客戶端(微服務)之間進行通訊,他們之間使用http協議進行通訊,

四 Springboot專案接入Sentinel

1 添加Sentinel依賴

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

專案其他關聯的部分配置

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.12.RELEASE</version>
</parent>

<properties>
    <maven.compiler.source>8</maven.compiler.source>
    <maven.compiler.target>8</maven.compiler.target>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    <spring-cloud.version>Hoxton.SR12</spring-cloud.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>${spring-cloud.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

2 組態檔資訊

server:
  port: 8081

spring:
  cloud:
    sentinel:
      transport:
     # 默認就是8719 port: 8719 dashboard: http://localhost:9090 web-context-unify: false application: name: sentinel-demo

組態檔說明:

spring.cloud.sentinel.transport.port埠配置會在應用對應的機器上啟動一個Http Server,該 Server會與Sentinel控制臺做互動,比如Sentinel控制臺添加了1個限流規則,會把規則資料 push給這個Http Server接收,Http Server 再將規則注冊到Sentinel 中,

spring.cloud.sentinel.transport.port:指定應用與Sentinel控制臺互動的埠,應用本地會起一個該埠占用的HttpServer,

客戶端需要添加jar包

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-transport-simple-http</artifactId>
    <version>1.8.5</version>
</dependency>

spring-cloud-starter-alibaba-sentinel依賴已經包含了上面的依賴,所以上面的依賴不需要再單獨添加,

 3 新建控制類

1 @RestController
2 public class DemoController {
3     @GetMapping("/demo/message")
4     public String message(){
5         return "message";
6     }
7 }

4 啟動專案,訪問控制類介面

http://localhost:8081/demo/message

五 接入限流埋點

1 HTTP埋點

Sentinel starter 默認為所有的HTTP服務提供了限流埋點,如果只想對HTTP服務進行限流,那么只需要添加依賴,無需修改代碼,(簡單說就是所有的 controller 層介面默認提供限流埋點)

2 自定義埋點

如果需要對某個特定的方法進行限流或降級,可以通過 @SentinelResource 注解來完成限流的埋點,示例代碼如下:

1 #service層
2 @Service
3 public class HelloServiceImpl implements HelloService {
4     @Override
5     @SentinelResource("hello")
6     public String hello() {
7         return "hello";
8     }
9 }
 1 #controller層
 2 @RestController
 3 public class HelloController {
 4     @Resource
 5     private HelloService helloService;
 6     @GetMapping("/hello")
 7     public String hello(){
 8         return helloService.hello();
 9     }
10 }

六 限流配置

1 認識流控規則

資源名:一般是我們的請求路徑url或注解@SentinelResource的value屬性值;

針對來源:來自于哪個應用;

閾值型別:分為QPS(每秒查詢數)或并發執行緒數;

單機閾值:單個節點的QPS或執行緒數閾值;

是否集群:被請求的服務是否集群部署;

流控模式:

  1. 直接,就是直接對該資源進行控制;
  2. 關聯,關聯某一個資源(/app2),被關聯的資源/app2達到閾值,則限制當前資源/test路徑的訪問;
  3. 鏈路,記錄指定鏈路上的流量;

流控效果:

  1. 快速失敗 ,直接限制;
  2. Warm Up,根據coldFactor(默認為3)的值,從閾值/coldFactor,經過預熱的時長,才達到設定的QPS閾值,比如設定QPS閾值為100,那么100/3 =33,用33作為最初的閾值,然后在10秒到達100后再開始限流;
  3. 排隊等待,在QPS閾值到達后,新的請求就等待,直到超時,可以適用于突發流量的請求;

2 直接限流

流量控制,其原理是監控應用流量的QPS(每秒查詢率) 或并發執行緒數等指標,當達到指定的閾值時,對流量進行控制,以避免被瞬時的流量高峰沖垮,從而保障應用的高可用性,

2.1 添加限流規則

在Sentinel dashboard配置/demo/message的限流規則,每秒最多允許訪問一次,超出訪問,就會限流,回傳默認的提示:Blocked by Sentinel (flow limiting)

說明:

QPS(Query Per Second),QPS 其實是衡量吞吐量(Throughput)的一個常用指標,就是說服務器在一秒的時間內處理了多少個請求 —— 我們通常是指 HTTP 請求,顯然數字越大代表服務器的負荷越高、處理能力越強,作為參考,一個有著簡單業務邏輯(包括資料庫訪問)的程式在單核心運行時可以提供 50 - 100 左右的 QPS,即每秒可以處理 50 - 100 個請求,

TPS(Transaction Per Second) 每秒鐘系統能夠處理的事務的數量,

QPS(TPS):每秒鐘 request/事務的數量  (此處 / 表示 或的意思)

并發數: 系統同時處理的request/事務數  (此處 / 表示 或的意思)

回應時間RT(Response Time):  一般取平均回應時間

理解了上面三個要素的意義之后,就能推算出它們之間的關系:

  QPS(TPS)= 并發數/平均回應時間  并發數除以平均回應時間

2.2 快速訪問,查看效果

打開瀏覽器頻繁訪問(使用F5 重繪瀏覽器訪問)(1秒內必須超過一次請求)

 

3 關聯限流

3.1 新建controller類

 1 @RestController
 2 @RequestMapping("/related")
 3 public class RelatedController {
 4     @GetMapping("/a")
 5     public String a(){
 6         return "關聯限流a";
 7     }
 8     @GetMapping("/b")
 9     public String b(){
10         return "關聯限流b";
11     }
12 }

3.2 新建關聯限流規則

這里關聯的資源是 /related/b(即保護介面b),上圖設定表示:如果介面b的QPS達到單機閾值“1”,則開始通過限流介面“a”,從而保護“b”,

3.3 測驗

測驗時,可以快速的使用F5 來重繪b,快速的切換到a,F5再重繪a,發現a被限流了

當介面b發送并發流量QPS值小于1時,介面“a”可以正常訪問,

關聯限流規則是保護重要服務的措施,即:如果某個服務(b)達到臨界值,則代表b資源不足,需要先限制不重要的服務(a),防止服務(a)繼續呼叫服務(b),

4 鏈路限流

4.1 新建服務類

1 @Service
2 public class HelloServiceImpl implements HelloService {
3     @Override
4     @SentinelResource("hello")
5     public String hello() {
6         return "hello";
7     }
8 }

4.2 新建controller類

 1 @RestController
 2 @RequestMapping("/chain")
 3 public class ChainController {
 4     @Resource
 5     private HelloService helloService;
 6     @GetMapping("/a")
 7     public String a(){
 8         return helloService.hello();
 9     }
10     @GetMapping("/b")
11     public String b(){
12         return helloService.hello();
13     }
14 }

4.3 新增組態檔application.yml

server:
  port: 8081

spring:
  cloud:
    sentinel:
      transport:
        port: 8719
        dashboard: http://localhost:9090
      # 禁止收斂URL的入口context,加上它否則鏈路規則不起作用
      web-context-unify: false
  application:
    name: sentinel-demo

4.4 新建鏈路流控規則

4.5 測驗鏈路流控規則

訪問介面a,當超過QPS設定值1,則介面“a”被限流,介面b同樣呼叫方法,但是不會被限流,

限流時會出現500錯誤

七 熔斷降級

上面實作了實作介面限流,但是在實際應用中,當我們的某個服務介面出現了問題,不能正常提供服務,或者該介面回應速度很慢,導致呼叫方大量請求堆積,此時需要將該介面降級服務,從而保護呼叫該介面的服務(消費者),快速回傳降級結果,防止因為過多的服務等待該介面的回傳,導致系統雪崩,

熔斷策略

1 Sentinel熔斷策略:慢呼叫比例

慢呼叫比例 (SLOW_REQUEST_RATIO):選擇以慢呼叫比例作為閾值,需要設定允許的慢呼叫 RT(即最大的回應時間),請求的回應時間大于該值則統計為慢呼叫,當單位統計時長(statIntervalMs)內請求數目大于設定的最小請求數目,并且慢呼叫的比例大于閾值,則接下來的熔斷時長內請求會自動被熔斷,經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求回應時間小于設定的慢呼叫 RT 則結束熔斷,若大于設定的慢呼叫 RT 則會再次被熔斷,

1.1 名詞解釋:

呼叫:一個請求發送到服務器,服務器給與回應,一個回應就是一個呼叫

RT(Response Time):回應時間,指系統對請求作出回應的時間

慢呼叫:當呼叫的時間(回應的實際時間)>設定的RT時,這個呼叫叫做慢呼叫

慢呼叫比例:在所有呼叫中,慢呼叫占有實際的比例,= 慢呼叫次數 / 總呼叫次數

比例閾值:自己設定的 , 慢呼叫次數 / 總呼叫次數>=比例閾值

閾值(threshold value)又叫臨界值,比如:水變成冰和水蒸氣

統計時長:時間的判斷依據

最小請求數:設定的呼叫最小請求數

1.2 狀態轉換

進入熔斷狀態判斷依據:當統計時長內,實際請求數目大于最小請求數目,慢呼叫比例> 比例閾值,進入熔斷狀態

熔斷狀態:在接下來的熔斷時長內請求會自動被熔斷

探測恢復狀態:熔斷時長結束后進入探測恢復狀態

結束熔斷:在探測恢復狀態,如果接下來的一個請求回應時間小于設定的慢呼叫 RT,則結束熔斷;否則,繼續熔斷,等待進入探測恢復狀態

1.3 實體測驗

1.3.1 新建controller類

 1 @RestController
 2 public class PollyController {
 3     @GetMapping("/polly")
 4     public String polly(){
 5         try {
 6             Thread.sleep(1000);
 7         } catch (InterruptedException e) {
 8             e.printStackTrace();
 9         }
10         return "熔斷降級";
11     }
12 }

1.3.2 配置熔斷規則

注意:Sentinel默認統計的RT上限是4900ms,超出此閾值的都會算作4900ms,若需要變更此上限可以通過啟動配置項-Dcsp.sentinel.statistic.max.rt=xxx來配置,

熔斷推測:

在1000毫秒,也就是1秒內,如果發送到/polly 的請求數數量大于1,并且在這些請求中,所有請求的回應時長(因為比例閾值為1,所以是所有的請求回應時長)都大于500毫秒,也就是都大于0.5秒的時候,進入熔斷狀態,

1.3.3 使用瀏覽器測驗熔斷

2 Sentinel熔斷策略:例外比例

例外比例:當單位統計時長(statIntervalMs)內請求數目大于設定的最小請求數目,并且例外的比例大于閾值,則接下來的熔斷時長內請求會自動被熔斷,經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,否則會再次被熔斷,例外比率的閾值范圍是 [0.0, 1.0],代表 0% - 100%,

2.1 新建controller類

 1 @RestController
 2 @Slf4j
 3 public class ExceptionController {
 4     int i = 0;
 5     @GetMapping("/exception")
 6     public String exception(){
 7         i++;
 8         if (i % 3 == 0){
 9             throw new RuntimeException("出現例外");
10         }
11         log.info("i的值為:{}", i);
12         return "例外";
13     }
14 }

2.2 配置熔斷規則

 2.3 使用瀏覽器測驗熔斷

3 Sentinel熔斷策略:例外數

例外數 (ERROR_COUNT):當單位統計時長內的例外數目超過閾值之后會自動進行熔斷,經過熔斷時長后熔斷器會進入探測恢復狀態(HALF-OPEN 狀態),若接下來的一個請求成功完成(沒有錯誤)則結束熔斷,否則會再次被熔斷,

3.1 配置熔斷規則

3.2 使用瀏覽器測驗熔斷

八 熔斷降級Spring Cloud示例

1 新建服務提供者工程

1.1 添加nacos依賴

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

1.2 添加組態檔

server:
  port: 8081

spring:
  application:
    name: sentinel-provider

  cloud:
    nacos:
      discovery:
        server-addr: http://IP地址:8848/nacos
        username: nacos
        password: nacos
        namespace: 75101df2-2f52-4100-aa37-f3c76a7fc1a0
        group: test-group

1.3 新建controller類

1 @RestController
2 @Slf4j
3 public class HelloController {
4     @GetMapping("/hello/{username}")
5     public String hello(@PathVariable String username){
6         log.info("我是一個服務提供者,我被呼叫了");
7         return username;
8     }
9 }

1.4 啟動服務提供者

2 新建服務消費者工程

2.1 添加主要依賴

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    <version>2.2.9.RELEASE</version>
</dependency>

2.2 添組態檔

server:
  port: 8082

spring:
  application:
    name: sentinel-consumer

  cloud:
    nacos:
      discovery:
        server-addr: http://IP地址:8848/nacos
        username: nacos
        password: nacos
        namespace: 75101df2-2f52-4100-aa37-f3c76a7fc1a0
        group: test-group

    sentinel:
      transport:
        dashboard: http://localhost:9090
        port: 8719   #sentinel默認的與服務之間互動的介面
# 打開openfeign對sentinel的支持
feign:
  sentinel:
    enabled: true

2.3 新建feign介面

1 @FeignClient(value = "https://www.cnblogs.com/gagaxiang/archive/2023/01/04/sentinel-provider", fallbackFactory = HelloFallbackFactory.class)
2 public interface HelloFeign {
3     @GetMapping("/hello/{username}")
4     String hello(@PathVariable String username);
5 }

2.4 新建FallbackFactory類

1 @Component
2 public class HelloFallbackFactory implements FallbackFactory<HelloFeign> {
3     @Override
4     public HelloFeign create(Throwable throwable) {
5         return username -> username + "說:我就是個被降級的";
6     }
7 }

2.5 新建controller類

1 @RestController
2 public class HelloController {
3     @Resource
4     private HelloFeign helloFeign;
5     @GetMapping("/hello/{username}")
6     public String hello(@PathVariable String username){
7        return helloFeign.hello(username);
8     }
9 }

2.6 啟動服務消費者,使用瀏覽器進行測驗

http://localhost:8082/hello/jack

可以正常訪問

停止服務提供者,降級起作用了

九 黑白名單(授權規則)

很多時候,我們需要根據呼叫來源來判斷該次請求是否允許放行,這時候可以使用Sentinel 的來源訪問控制(黑白名單控制)的功能,來源訪問控制根據資源的請求來源(origin)限制資源是否通過,

  1. 若配置白名單則只有請求來源位于白名單內時才可通過;
  2. 若配置黑名單則請求來源位于黑名單時不通過,其余的請求通過,

1 配置規則

來源訪問控制規則(AuthorityRule)非常簡單,主要有以下配置項:

resource:資源名,即限流規則的作用物件,

limitApp:對應的黑名單/白名單,不同origin 則用“,” 分隔,如 appA,appB,

strategy:限制模式,AUTHORITY_WHITE 為白名單模式,AUTHORITY_BLACK 為黑名單模式,默認為白名單模式,

2  新建controller類

1 @RestController
2 public class WhiteAndBlackController {
3     @GetMapping("/list")
4     public String hello(){
5         return "hello";
6     }
7 }

3 新增介面來源類

流控應用:Sentinel提供了RequestOriginParser來處理介面來源,

1 @Component
2 public class TestRequestOrigin implements RequestOriginParser {
3     @Override
4     public String parseOrigin(HttpServletRequest httpServletRequest) {
5         // 表示請求引數中含有server鍵
6         String server = httpServletRequest.getParameter("server");
7         return server;
8     }
9 }

4 配置白名單規則(黑名單的作用與白名單相反)

 5 啟動應用,使用瀏覽器訪問

只有當引數值與規則中配置的流控應用相等時,才能正常訪問

十 持久化

默認情況下,sentinel-dashboard 中的規則是存盤在微服務記憶體中,重啟后就會丟失,

持久化指的是,一旦重啟sentinel的微服務,sentinel配置的各種規則不會丟失,

1 Sentinel結合Nacos持久化配置

Sentinel持久化支持的型別有,詳情見:

com.alibaba.cloud.sentinel.datasource.config.DataSourcePropertiesConfiguration

1.1 添加依賴

<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-datasource-nacos</artifactId>
    <version>1.8.5</version>
</dependency>

1.2 添加組態檔

  port: 8081

spring:
  cloud:
    nacos:
      discovery:
        server-addr: http://IP地址:8848/nacos
        username: nacos
        password: nacos
        namespace: 75101df2-2f52-4100-aa37-f3c76a7fc1a0
        group: test-group
    sentinel:
      transport:
        port: 8719
        dashboard: http://localhost:9090
      datasource:
        ds1:
          nacos:
            server-addr: http://IP地址:8848/nacos
            dataId: sentinel-datasource-nacos.json
            namespace: 75101df2-2f52-4100-aa37-f3c76a7fc1a0
            groupId: test-group
            # 只支持json和xml
            data-type: json
            #authority(授權規則)、degrade(降級規則)、flow(流控規則)、param(熱點規則)、system(系統規則)五種規則持久化到Nacos中, 另外還增加網關的兩個(api分組,限流)
            #rule-type這個屬性沒有提示,為空時,會報空指標錯誤
            rule_type: flow
  application:
    name: sentinel-datasource-nacos

1.3 登陸nacos,新建配置規則sentinel-datasource-nacos.json

[
{
"resource": "/user/findById",
"limitApp":"default",
"grade":1,
"count":1,
"strategy":0,
"controlBehavior":0,
"clusterMode":false
}
]

配置說明:

resource:資源名稱

limitApp:來源應用

grade:閥值型別,0---執行緒數,1---QPS

count:單機閥值

strategy:流控模式,0---直接,1---關聯,2---鏈路

controlBehavior:流控效果,0---快速失敗,1---warmUp,2---排隊等待

clusterMode:是否集群

參考官方檔案:https://sentinelguard.io/zh-cn/docs/flow-control.html

注意:

  1. 此時如果是Nacos集群,每個節點務必要配置到同一個資料庫上,并且保證每個節點都可用,如果有的節點宕掉了可能會導致配置持久化失敗,
  2. 部署在nacos上的組態檔的名字并沒有太多要求,只需要跟微服務專案中yml檔案中配置的dataId一致即可,

1.4 查看sentinel流控規則,并測驗訪問

將配置規則持久化進Nacos保存,重啟使用sentinel的微服務,只要訪問一下基于流控規則的url,流控規則就會顯示在sentinel的界面上,此時,持久化生效,只要Nacos里面的配置不洗掉,針對微服務上Sentinel上的流控規則持續

有效,

1.5 問題

目前有一個小問題,當我們在sentinel dashboard控制臺更新或者新加規則,nacos里面的規則并不能得到更新;

2 其他限流規則

2.1 Sentinel熔斷降級規則說明

參考地址:https://sentinelguard.io/zh-cn/docs/circuit-breaking.html

2.2 Sentinel【熱點規則】熱點引數規則

參考地址:https://sentinelguard.io/zh-cn/docs/parameter-flow-control.html

2.3 Sentinel系統規則 

參考地址:https://sentinelguard.io/zh-cn/docs/origin-authority-control.html

十一 Spring Cloud Alibaba Sentinel三種保護應用方式

1 直接攔截我們所有controller的請求url路徑

Sentinel為springboot程式提供了一個starter依賴,由于sentinel starter依賴默認情況下就會為所有的HTTP服務提供限流埋點,所以在springboot 中的Controller都可以受到Sentinel的保護;

只需為應用添加 spring-cloud-starter-alibaba-sentinel依賴,所有的HTTP介面都能獲得Sentinel保護,當然,我們還需要為Sentinel配置保護的規則;底層通過一個攔截器對請求url進行攔截:

com.alibaba.csp.sentinel.adapter.spring.webmvc.SentinelWebInterceptor

可以通過如下配置關閉對微服務的保護:

#關閉sentinel對controller的url的保護

spring.cloud.sentinel.filter.enabled=false

2 通過代碼方式保護應用(只是了解)

這種方式就是手動寫代碼,稍微比較繁瑣

 1 @GetMapping("/test3/{app}")
 2 public String test3(@PathVariable("app") String app) {
 3    System.out.println("/test3/{app} --> " + app);
 4    Entry entry = null;
 5    try {
 6       entry = SphU.entry("test3");
 7       return restTemplate.getForObject("http://29-nacos-discovery-provider/test", String.class);
 8    } catch (BlockException e) {
 9       e.printStackTrace();
10       return "熔斷降級了...";
11    } finally {
12       if (entry != null) {
13          entry.exit();
14       }
15    }
16 }

3 通過@SentinelResource(value = "https://www.cnblogs.com/gagaxiang/archive/2023/01/04/app")注解保護應用

屬性

作用

是否必須

value

資源名稱

entryType

entry型別,標記流量的方向,取值IN/OUT,默認是OUT

blockHandler

處理BlockException的函式名稱,函式要求:
1. 必須是 public
2.回傳型別與原方法一致
3. 引數型別需要和原方法相匹配,并在最后加 BlockException 型別的引數,
4. 默認需和原方法在同一個類中,若希望使用其他類的函式,可配置 blockHandlerClass ,并指定blockHandlerClass里面的方法,

blockHandlerClass

存放blockHandler的類,對應的處理函式必須static修飾,否則無法決議,其他要求:同blockHandler,

fallback

用于在拋出例外的時候提供fallback處理邏輯,fallback函式可以針對所有型別的例外(除了 exceptionsToIgnore 里面排除掉的例外型別)進行處理,函式要求:
1. 回傳型別與原方法一致
2. 引數型別需要和原方法相匹配,Sentinel 1.6開始,也可在方法最后加 Throwable 型別的引數,
3.默認需和原方法在同一個類中,若希望使用其他類的函式,可配置 fallbackClass ,并指定fallbackClass里面的方法,

fallbackClass

存放fallback的類,對應的處理函式必須static修飾,否則無法決議,其他要求:同fallback,

defaultFallback

用于通用的 fallback 邏輯,默認fallback函式可以針對所有型別的例外(除了 exceptionsToIgnore 里面排除掉的例外型別)進行處理,若同時配置了 fallback 和 defaultFallback,以fallback為準,函式要求:
1. 回傳型別與原方法一致
2. 方法引數串列為空,或者有一個 Throwable 型別的引數,
3. 默認需要和原方法在同一個類中,若希望使用其他類的函式,可配置 fallbackClass ,并指定 fallbackClass 里面的方法,

exceptionsToIgnore

指定排除掉哪些例外,排除的例外不會計入例外統計,也不會進入fallback邏輯,而是原樣拋出,

exceptionsToTrace

需要trace的例外

Throwable

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/541170.html

標籤:其他

上一篇:FPGA:乒乓球比賽模擬機的設計

下一篇:如何創建Django專案

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more