SpringCloud Alibaba 初心者から熟練者まで - Sentinel

SpringCloud Alibaba 初心者から熟練者まで - Sentinel

1. インフラ整備

ここに表示されるデモは、Maven の親子プロジェクトを通じて管理されます。親子観察管理を使用する利点は次のとおりです。

  • 1. コードは一元化されており、集中管理、ダウンロードが容易になります。
  • 2. 一元管理により学習コストが低くなり、プロジェクトが受け入れられやすくなります

1. 親プロジェクトの作成

アイデアを使用します。file–>new–>project–>maven を使用して親プロジェクトを作成します。コンパイル時に親プロジェクトがサブプロジェクトを管理するという目的を達成できるように、親プロジェクトは pom 内にある必要があります。pom 内にない場合は、pom 内にない場合は、親プロジェクトの下に作成できません。サブプロジェクトは正しく作成されています。
このデモでは一元的なバージョン管理が採用されており、次の 3 つのバージョンに制限するだけで済みます。これらを dependencyManagement に配置してバージョンを指定し、同時にタイプとスコープを宣言して、グローバル コンポーネントのバージョン管理を実現するだけで済みます。関数は親タグと似ていますが、親はバージョンの依存関係を管理するために親プロジェクトを宣言することしかできません。 dependencyManagement の依存関係は複数の依存関係をサポートできます。

  • スプリングブートのバージョン: 2.6.11
  • SpringCloud バージョン: 2021.0.4
  • SpringCould Alibaba バージョン: 2021.0.4.0

alibaba、クラウド、ブート間のバージョンの対応が不明な場合は、ここを参照してください: SpringCloud コンポーネントのバージョンの依存関係

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

以下は、親プロジェクトの完全な pom ファイルです。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <!--这里不使用parent来管理整体的jar的版本,统一放在dependencymanager中进行管理-->
    <!--<parent>-->
    <!--<groupId>org.springframework.boot</groupId>-->
    <!--<artifactId>spring-boot-starter-parent</artifactId>-->
    <!--<version>3.1.3.RELEASE</version>-->
    <!--<relativePath/> &lt;!&ndash; lookup parent from repository &ndash;&gt;-->
    <!--</parent>-->
    <groupId>com.cheng</groupId>
    <artifactId>spring-cloud-alibaba-base</artifactId>
    <packaging>pom</packaging>
    <version>1.0.0</version>
    <modules>
        <module>order-server</module>
        <module>stock-server</module>
    </modules>

    <name>spring-cloud-alibaba-base</name>
    <description>alibaba父工程</description>
    <properties>
        <java.version>8</java.version>
        <Spring-boot-version>2.6.11</Spring-boot-version>
        <Spirng-cloud-version>2021.0.4</Spirng-cloud-version>
        <Spring-cloud-alibaba-version>2021.0.4.0</Spring-cloud-alibaba-version>
    </properties>

    <dependencyManagement>
        <!--通过此模块来规范boot和cloud的所有组件版本,所有的子工程将不需要考虑组件的版本问题-->
        <dependencies>
            <!--这种写法和写在parent中作用一样,注意type和scope不可省略-->
            <!--这种写法的优点是可以声明多个父级的项目包版本依赖,而parent只能由一个-->
            <!--这是springboot相关包的版本管理-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-parent</artifactId>
                <version>${Spring-boot-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--这是alibaba组件的版本管理-->
            <dependency>
                <groupId>com.alibaba.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${Spring-cloud-alibaba-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!--这是cloud的组件的版本管理,也可以使用pring-cloud-dependencies-parent,但是使用下面的更好-->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${Spirng-cloud-version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>

    </dependencyManagement>


    <!--dependencies中的包会直接被子工程继承,而dependencyManagement的包不手动引入,则不会继承-->
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

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

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

</project>

2. サブプロジェクトの作成

サブプロジェクトの作成も同様です。例を示します: 親プロジェクトを右クリック→新規→モジュール→spring-initializr。ここでは Spring-initializr は使用しません。Maven も使用できますが、 spring-initializr を使用すると便利で、起動クラスや設定ファイルなどを自分で作成する必要はありません。IDEA が比較的新しい場合 (私の知る限り、IDEA2021 以下は使えないようです)、spring-initializr を使用してサードパーティのスキャフォールディングを指定することもできます。Alibaba のサードパーティのスキャフォールディング アドレスを使用することをお勧めします。 。https://start.aliyun.com、このスキャフォールディングは Springcloud コンポーネントにとってよりフレンドリーであり、より多くの Alibaba コンポーネントも含まれています
(注: IDEA のコミュニティ バージョンは Spring Initializr 関数をサポートしていません)
ここに画像の説明を挿入します
。サブプロジェクト:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.cheng</groupId>
        <artifactId>spring-cloud-alibaba-base</artifactId>
        <version>1.0.0</version>
    </parent>
    <groupId>com.cheng</groupId>
    <artifactId>order-server</artifactId>
    <version>1.0.0</version>
    <name>order-server</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>17</java.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

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

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

</project>

この時点では、単純にシェルフを構築し、サービスごとにさまざまなコンポーネントと依存関係を導入します。
上記の親子プロジェクトの作成が十分に詳細ではないと思われる場合は、ここを読むことをお勧めします: Maven を使用した親子プロジェクトの作成の詳細な説明

2. Sentinel と Spring Cloud の統合

Sentinel の詳細な紹介については、公式ドキュメントを参照してください:
Sentinel 公式 Web サイト
Sentinel の githubはここでさらに詳しく説明されています

1. マイクロサービスで考えられる問題

  • 1. トラフィックが急増し、CPU の能力が高すぎてリクエストを正常に処理できなくなります。
  • 2. データがウォームアップされていないことによるキャッシュの故障
  • 3. メッセージが多すぎるとメッセージ バックログが発生する
  • 4. SQL が遅いとデータベース接続がいっぱいになる
  • 5. サードパーティのシステムが応答せず、クリックを繰り返すとスレッドがいっぱいになります。
  • 6. システム異常メモリが正常に解放できない OOM
  • 7. サーバーのメモリボトルネック、プログラムが異常終了する

上記の問題は、サービスの単一障害点につながる可能性があり、サービスに追加の処理を追加しないと、あるシステムがハングアップすると、そのシステムに依存するシステムにも異常が発生し、その結果、サービスに問題が発生します。ドミノ倒しのように次々とサービスが発生し、最終的には広いエリアでサービスが利用できなくなることを、サービス雪崩と呼びます。サービス雪崩は耐え難いもので、一度発生すると基本的にシステムが利用できなくなるため、ユーザーにとって非常に不親切であり、多大なユーザーの損失につながります。
したがって、シナリオに基づいてサービスが利用できない問題を解決する必要があります。これには、分散システムのトラフィックガードと呼ばれる Sentinel が使用されます。その主な役割は、システムの安定性 (信頼性) と回復性の確保です。 )、複数のシステムのフォールト トレランス メカニズムをサポートします。一般的なメカニズムには次のものがあります。

  • 1. タイムアウト機構
    :タイムアウト時間を設定し、指定された時間内に処理し、タイムアウト後にタイムアウトロジックを処理します。
  • 2.電流制限メカニズムは
    QPSに基づいてサービスプロセスを制御できます
  • 3. スレッド分離メカニズムは
    スレッド プールを使用してリクエストを管理し、余分な部分に対して他の処理戦略を定義できます。
  • 4. サービス サーキット ブレーカー:
    サービスが定義されたサーキット ブレーカー標準またはダウングレード標準に達すると、二次情報処理がサービス上で実行されます。これにはメッセージ キュー処理が含まれる場合もあれば、最終的な整合性処理を待機するためにデータベースに保存される場合もあります。
  • 5. サービスのダウングレード
    : サービス例外処理の粒度がサービスの二次処理を必要とする点を除けば、この感情は実際にはサービス サーキット ブレーカーに似ていると感じます。

Sentiael は上記のシナリオの処理において優れた仕事をしており、同時実行性の高いシナリオでもサービスの可用性と安定性を十分に保証できます。アリババが作る製品は高品質である必要があり、使用するだけで終わりです。現在、市場に出ているオープン ソースは Sentinel だけですが、前身である hystrix は更新を停止しています。簡単な比較を次に示します。
ここに画像の説明を挿入します

2.SpringCloud は Sentinel を統合してダッシュボードを構築します

Sentinel は Springboot プロジェクトに統合でき、アリババは Sentinel の迅速な統合を容易にする対応するスターターも提供します。アリババが提供するスターターには、使用する必要があるすべての jar パッケージが含まれています (OpenFeign、Gateway などを統合する jar を除く)。 。一緒に体験してみましょう。ここで使用されるバージョンは、最上位バージョンとの一貫性を宣言する必要はありません。実際に使用しているのはSentinel1.8.5です

ダッシュボードの公式ドキュメントのアドレス: Sentinel コンソール
ダッシュボードのダウンロード アドレス: Sentinel-Dashboard ダウンロード
ダッシュボードのデフォルトのアカウント パスワード: Sentinel/sentinel の
構築は非常に簡単です。公式 Web サイトから対応する jar をダウンロードするだけです。ダッシュボードは標準の SpringBoot プロジェクトです。 java コマンドを使用して直接起動できます。

java -Dserver.port=8080 \
-Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dproject.name=sentinel-dashboard \
-jar sentinel-dashboard-1.8.5.jar

デフォルトのユーザー名とパスワードを変更する場合は、ユーザー名とパスワードのパラメーターを追加できます。

java -Dserver.port=8080 \
-Dcsp.sentinel.dashboard.server=localhost:8080 \
-Dproject.name=sentinel-dashboard \
-Dsentinel.dashboard.auth.username=admin \ 
-Dsentinel.dashboard.auth.password=admin \ 
-jar sentinel-dashboard-1.8.5.jar

すぐに検証したい場合は、Git Bash をローカルで起動すればすぐに検証できますし、
ダッシュボード自体をダッシュ​​ボードに表示したくない(何を使用するかを制御するのは実際には役に立たない)場合は、次のように、project.name を直接キャンセルでき、csp.sentinel.dashboard.server の設定は OK です。

java -Dserver.port=8080 \
-Dsentinel.dashboard.auth.username=admin \
-Dsentinel.dashboard.auth.password=admin \
-jar sentinel-dashboard-1.8.5.jar

実際に使ってみると、実際に使ってみてもOKなので、
ここに画像の説明を挿入します
内部の各種構成については割愛しますが、後でZhuo Yiが紹介します。

3 SpringCloud は Sentinel を統合します

  • 1. 関連する jar を紹介する
    <!--sentinel依赖-->
    <dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
  • 2 構成の追加:
    この手順では、Sentinel が Dashboard と正常に通信できるように、Dashboard のアドレスを指定します。
    # 已省略关系不大的配置
    spring:
      application:
        # sennel使用该名称注册到Dashboard
        name: stock-server 
      cloud:
        sentinel:
          transport:
            port: 8719 # dashboard控制面版与sentinel通信的本地端口
            dashboard: 127.0.0.1:8080   # sentinel控制面板地址
    
  • 3. サービスが正常にダッシュボードに登録されるかテストします。
    デフォルトではサービス起動後は直接ダッシュボードに登録されず、リクエストがあった場合のみダッシュボードに登録されます。ダッシュボードでサービスを確認すると、各サービスの下に次の構成監視メニューが表示されます。リアルタイム監視データを確認できるように、ここでいくつかのリクエストを行っていますが、リアルタイム データがない場合、ここには表示されません。
    ここに画像の説明を挿入します
    このようにして、Sentinel と Dashboard の構築が簡単に完了しました。

3. サービスのダウングレード

5 つのルールについて詳しく説明する前に、まずサービスの低下について話さなければなりません。サービスのダウングレードは、ユーザー エクスペリエンスを向上させる方法です。ユーザーのリクエストがシステム上の理由で拒否された場合、システムは、ユーザーには受け入れられるが、ユーザーには満足できない、事前に設定された結果を返します。この種のリクエスト処理サービスの低下サービス低下がしきい値に達すると、サーキットブレーカーがトリガーされる まず、Spring Cloud における一般的な低下処理方法を見てみましょう。

1 サービスのダウングレード - Sentinel

ここでは Sentinel のアノテーション @SentinelResource を使用する必要があります。このアノテーションは Sentinel の中核となるアノテーションです。このアノテーションの使用方法と各パラメーターの詳細については後ほど簡単に説明します。このアノテーションはサービスのダウングレードにのみ使用されるため、リソースを登録する必要はありません(値が宣言された場合にのみ登録されます)。このアノテーションには、サービスのダウングレードに関連する 4 つの属性があります。
@SentinelResource アノテーションの公式の詳細な紹介:アノテーション @SentinelResource

  • フォールバックとフォールバッククラスのダウングレード
  • defaultFallback および fallbackClass のダウングレード
  • ExceptionsToIgnore 属性: 例外を無視します。無視された例外はダウングレードをトリガーしません。
  • 1. ダウングレード: フォールバック
    フォールバックは、ダウングレード処理メソッドのメソッド名である文字列を渡す必要があります。では、このメソッドはどのように記述すればよいでしょうか? ダウングレード メソッドは次のルールに従う必要があります。

    • ①戻り値の型は元の関数の戻り値の型と一致している必要があります。
    • ② メソッドパラメータリストは元の関数と一致している必要があります。そうでない場合は、対応する例外を受け取るために追加の Throwable 型パラメータを追加できます。
    • ③ フォールバック関数はデフォルトで元のメソッドと同じクラスにある必要があります。他のクラスの関数を使用したい場合は、対応するクラスの Class オブジェクトとして fallbackClass を指定できます。対応する関数は静的関数 (fallbackClass を使用する場合) である必要があり、そうでない場合は解析できません。

    以下はサンプル コードです。ここに新しい設定を追加する必要はありません。これは 2.2 の設定に基づいています。

    import com.alibaba.csp.sentinel.annotation.SentinelResource;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author pcc
     */
    @Slf4j
    @RefreshScope // 动态刷新nacos配置注解
    @RestController
    @RequestMapping("/stock")
    public class StockController {
          
          
    
        @Value("${name}")
        String name;
    
    
    
        @RequestMapping("/addStock")
        @SentinelResource(fallback = "addStockFallBack")
        public void addStock() throws Exception{
          
          
            int i = 1/0;
            log.info("add stock start: {}",name);
    
        }
    
        /**
         * 这是方法降级的 方法
         * 这里可以不使用 static
         * @param throwable 触发的异常
         */
        public static void addStockFallBack(Throwable throwable){
          
          
            log.info("addStock 触发方法降级: {}", throwable.getMessage());
        }
    
    }
    

    以下は実行中のスクリーンショットです。
    ここに画像の説明を挿入します

  • 2 ダウングレード: フォールバックは、fallbackClass および例外ToIgnore と連携します。
    インターフェイスが多数ある場合、すべてのダウングレード メソッドをインターフェイスに置くことは明らかに不適切であり、非常に乱雑に見えます。そのため、実際のシナリオでは、常にコントローラーのダウングレード メソッドを置きます。別のクラスで、@SentinelResource の fallbackClass を使用して対応するクラスを指定し、fallback を使用してダウングレード メソッドを指定すると、ダウングレード メソッドとインターフェイス クラスの間の結合を分離できます。一緒に使用されます。
    これはサービスがダウングレードされるクラスです

    /**
     * @author pcc
     * 这是降级类
     */
    @Slf4j
    public class StockDegrade {
          
          
        /**
         * 这是类降级的 方法
         * @param a 触发的异常
         */
        public static void addStock(Throwable a) {
          
          
            log.info("add stock 类级降级: {}",a.getMessage());
    
        }
    }
    
    

    これはダウングレードに使用されるインターフェイスです。

    import com.alibaba.csp.sentinel.annotation.SentinelResource;
    import com.cheng.stockserver.sentineldegrade.StockDegrade;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author pcc
     */
    @Slf4j
    @RefreshScope
    @RestController
    @RequestMapping("/stock")
    public class StockController {
          
          
    
        @Value("${name}")
        String name;
        
        @SentinelResource(fallback = "addStock",fallbackClass = StockDegrade.class,exceptionsToIgnore =  {
          
          ArithmeticException.class})
        @RequestMapping("/addStock")
        public void addStock() throws Exception{
          
          
            log.info("add stock start: {}",name);
            throw new RuntimeException("运行时异常");
    
        }
    
    }
    

    上に示したように、fallbackClass を使用してダウングレード メソッドが配置されているクラスを指定し、fallback を使用して対応するダウングレード メソッドを指定します。これにより、ダウングレード メソッドを別のダウングレード クラスに分離できます。上記のコードでは、RuntimeException を手動でスローしていますが、ArithmeticException がスローされた場合、サービスのダウングレード メソッドには入らず、直接上向きにスローされ、サービスは直接例外になります (統一された例外処理がないと仮定します)。ここでは ArithmeticException のみが無視されるため、引き続きダウングレード メソッドに入ります。
    特記事項: ダウングレードされたクラスを指定する場合、ダウングレードされたメソッドは静的である必要があります。静的でない場合は解析できません。

  • 3 ダウングレード:defaultFallback は、fallback、fallbackClass、ExceptionsToIgnore と連携します。defaultFallback を
    メソッドに適用すると、フォールバックの使用法と完全に一致します。必要なルールも同じです。上記の fallback をdefaultFallback に置き換えることは完全に実現可能です2つの例。ここで説明する必要のある、defaultFallback の特別な機能が 2 つあります。

    • defaultFallback はクラスを変更できます (公式ドキュメントには 1.8.0 からサポートされると記載されています。すべてのインターフェイスをサポートするデフォルトのダウングレード メソッドであるはずです。テスト後はあまりサポートされていません)
    • defaultFallback と fallback が同時に設定されている場合、fallback が有効になり、defaultFallback は失敗します。

    以下は、defaultFallbck と fallback が同時にインターフェースを変更した場合に誰が有効になるかを示しています。

    import com.alibaba.csp.sentinel.annotation.SentinelResource;
    import com.cheng.stockserver.sentineldegrade.StockDefaultDegrade;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.cloud.context.config.annotation.RefreshScope;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
     * @author pcc
     */
    @Slf4j
    @RefreshScope
    @RestController
    @RequestMapping("/stock")
    public class StockController {
          
          
    
        @Value("${name}")
        String name;
    
    
        /**
         * 这里同时使用了fallback 、defaultFallback
         * 当同时使用时,只有fallback生效
         *
         */
        @SentinelResource(
                defaultFallback = "stockDefaultFallback",
                fallback = "addStockFallback",
                fallbackClass = StockDefaultDegrade.class,
                exceptionsToIgnore = ArithmeticException.class)
        @RequestMapping("/addStock")
        public void addStock(){
          
          
            log.info("add stock start: {}",name);
            throw new RuntimeException("运行时异常1");
    
        }
        
    }
    

    以下は、ダウングレードされたクラスと対応するメソッドです。

    import lombok.extern.slf4j.Slf4j;
    
    /**
     * @author pcc
     * 这是defaultFallback的降级类
     */
    @Slf4j
    public class StockDefaultDegrade {
          
          
    
        /**
         * 这是默认降级方法
         * @param throwable
         */
        public static void stockDefaultFallback(Throwable throwable){
          
          
            log.info("触发defaultFallback的降级方法:" + throwable.getMessage() + " ");
        }
    
        /**
         * 这是fallback用的指定降级方法
         * @param throwable
         */
        public static void addStockFallback(Throwable throwable){
          
          
            log.info("触发addStockFallback的降级方法:" + throwable.getMessage() + " ");
        }
    }
    

    対応するインターフェイスを呼び出すと、実際にトリガーされる唯一のダウングレード メソッドが、フォールバックで指定されたダウングレード メソッドであることがわかります。
    ここに画像の説明を挿入します

2 Sentinel は OpenFeign を統合します

OpenFeign は、サービス低下の処理をデモンストレーションするためにのみ Sentinel をここに統合しており、他の機能を拡張するものではありません。OpenFeign は、わずか 2 つの小さなステップで Sentinel を統合します。

  • 1 Sentinel の依存関係をインポートする
    <!--sentinel依赖-->
    <dependency>
       <groupId>com.alibaba.cloud</groupId>
       <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
    </dependency>
    
  • 2 Sentinel の OpenFeign サポートを有効にし
    、yml またはプロパティで設定します。
    # 已省略关系不大的配置
    feign:
      sentinel:
        enabled: true # 开启sentinel对feign的支持
    
    Sentinel に追加の設定を追加することなく、直接使用できます。

3 OpenFeign はサービスの低下を定義します

OpenFeign は 2 つの方法でサービスをダウングレードできますが、Sentinel または Hystrix を統合する必要があります。ここでは例として Sentinel の統合を取り上げます。

  • 1 FeignClient でフォールバックを使用してダウングレード クラスを指定する
  • 2 fallbackFactoryを使用してFeignClientでダウングレードクラスを指定します

両方がサポートされているため、それらの間に違いがあるはずです。主な違いは、フォールバックは例外を取得できないことですが、fallbackFactory は特定の例外を知ることができます。特定の例外を知ることで、異なる例外に応じて異なる処理を実行できるため、実際のシナリオではほとんどの例外が認識されます。 fallbackFactory を使用します (フォールバックを使用するものもあります)。以下に詳しく説明します。

    1. フォールバック サービスのダウングレード
      フォールバックを使用するには、次の条件を満たす必要があります
      1. fallbackで指定したクラスはSpringコンテナで管理する必要がある
      1. fallback で指定されたクラスは、FeignClient で変更された feign インターフェイスを実装する必要があります。

    このようにして、クラスをフォールバックに渡すことができ、例外が発生すると、オーバーライドする対応するメソッドにその例外が導入されます。以下はテスト コードです。
    これは偽のインターフェイス コードです。

    import org.springframework.cloud.openfeign.FeignClient;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    /**
     * @author pcc
     * url: 用于指定三方接口,通过url指定的接口不会从注册中心获取服务列表,而是直接通过接口名拼接地址
     * name:用以声明feign调用的服务,这个必须与注册中心服务名保持一致
     * path:控制器上的类路径,如果不写path在方法上写全路径也是一样的
     * configuration:配置类,可以配置一些公共的参数,只对当前类下的接口生效,属于局部配置
     * fallback : 声明降级类
     *
     */
    @FeignClient(name = "stock-server",path = "/stock",
            fallback = StockFeignControllerDegrade.class)
    public interface StockFeignController {
          
          
    
        @RequestMapping("/addStock")
        void addStock();
    }
    

    以下はダウングレード クラスのコードです。非常にシンプルですが、どのような例外がサービスのダウングレードを引き起こしたのかを知ることはできません。

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.stereotype.Component;
    
    /**
     * @author pcc
     */
    @Slf4j
    @Component
    public class StockFeignControllerDegrade implements StockFeignController{
          
          
        @Override
        public void addStock() {
          
          
            log.info("addStock: 降级方法处理中。。。");
        }
    }
    

    次に、それをテストすると、サーバー例外が発生すると、通常はダウングレード メソッドに入ることがわかります (サービス プロバイダー コードが例外をスローします)。
    ここに画像の説明を挿入します

    1. fallbackFactory サービスのダウングレード
      fallbackFactory を使用するには、次のルールに従う必要があります。
    • 1 実装クラスは Spring で管理する必要がある
    • 2 実装クラスは、FallbackFactory インターフェイスを実装し、ジェネリック タイプの Feign インターフェイスを渡す必要があります。

    以下は Feign インターフェースのコードです。

    /**
     * @author pcc
     * url: 用于指定三方接口,通过url指定的接口不会从注册中心获取服务列表,而是直接通过接口名拼接地址
     * name:用以声明feign调用的服务,这个必须与注册中心服务名保持一致
     * path:控制器上的类路径,如果不写path在方法上写全路径也是一样的
     * configuration:配置类,可以配置一些公共的参数,只对当前类下的接口生效,属于局部配置
     * fallback : 声明降级类
     * fallbackFactory: 声明降级工厂类
     *
     */
    @FeignClient(name = "stock-server",path = "/stock",
            fallbackFactory = StockFeignCallBackFactory.class)
    public interface StockFeignController {
          
          
    
        @RequestMapping("/addStock")
        void addStock();
    }
    

    以下はダウングレードファクトリーの実装クラスです。

    import lombok.extern.slf4j.Slf4j;
    import org.springframework.cloud.openfeign.FallbackFactory;
    import org.springframework.stereotype.Component;
    
    /**
     * @author pcc
     */
    @Slf4j
    @Component
    public class StockFeignCallBackFactory implements FallbackFactory<StockFeignController> {
          
          
        @Override
        public StockFeignController create(final Throwable cause) {
          
          
            return new StockFeignController() {
          
          
                @Override
                public void addStock() {
          
          
                    log.info("addStock:fallbackFactroy降级中:{}",cause.getMessage());
                }
            };
        }
    }
    

    例外の詳細を示すために、上記のコードは Throwable 原因を最終的な Throwable 原因に変更します。そうしないと、内部クラスは変数原因を操作できません (ラムダを頻繁に作成する場合は、この問題に精通している必要があります)。実行後、以下の図でダウングレード メソッドでリモート インターフェイスの例外情報を取得したことがわかります。
    ここに画像の説明を挿入します
    追加する必要があるのは、サービスの低下と統合例外処理の関係です。
    サービスのダウングレードによって処理される例外は、当然のことながら、グローバル例外処理ではキャッチできません。グローバル例外処理は、秘密のダウングレード プロセスと見なすことができます

4. 電流制限サーキットブレーカーのルール: DegradeRule

注: 現在の使用環境は SringCloud です。環境が異なる場合、サーキット ブレーカーの使用方法が若干異なります。
サーキット ブレーカーの話の前に、ダウングレード処理について説明します。サービスのダウングレード処理は、downgrade メソッドを宣言することで実装しますが、前節では @SentinelResource または @FeignClient を使用する 2 つの処理方法を紹介しました。これらはすべて、サービス例外が発生したときにトリガーされるダウングレード メソッドを実装できます。では、サーキットブレーカーとサービス低下との間にはどのような関係があるのでしょうか? サービスサーキットブレーカーのルールを設定する必要があります。たとえば、1 秒以内に 10 件のリクエストがあり、そのうち 5 件が異常である場合にサーキットブレーカーを設定します。ダウングレード メソッドは、サーキット ブレーカーがトリガーされると呼び出されます。ここで質問がありますか? 通常の例外はダウングレード メソッドを呼び出し、サーキット ブレーカーも例外メソッドを呼び出します。では、なぜサーキット ブレーカーを設定する必要があるのでしょうか? デフォルトでダウングレード メソッドを使用するだけで十分ではないでしょうか? 答えは間違いなく「いいえ」です。そうでない場合、なぜサーキット ブレーカーが必要なのでしょうか? サーキット ブレーカーは、異常なシナリオまたはリソースが制限されたシナリオ (呼び出しが異常な場合、実際、これはスレッド リソースの無駄です。応答が遅く、複数のサービスがまだこのインターフェイスを呼び出している場合も、リソースの無駄です。もちろん、それがコア サービスの場合は、別途議論する必要があります)。したがって、サーキット ブレーカーはサーキット ブレーカー時間の概念を提供します。サーキット ブレーカーがトリガーされると、サーキット ブレーカー時間が与えられます。サーキット ブレーカー期間中、現在のインターフェイスまたはリソースによって受信されたリクエストは、メソッドに入るのではなく、ダウングレード メソッドに直接入ります。 。これにより、サービスが異常な状態にある場合、一連の処理を行ってリソースを占有する必要がなくなり、ダウングレード処理を行うだけで済むなど、多くの問題を解決できます。時間がサーキット ブレーカー時間の制限に達すると、次のリクエストがメソッドに入ります。現在のメソッドが一度ダウングレードをトリガーすると、サーキット ブレーカー ルールを判断するのではなく、サーキット ブレーカーは直接サーキット ブレーカーになります。正常であればサーキットブレーカーは解除されます。
Sentinel のサーキット ブレーカーは、スロー コール率、例外率、例外数の 3 つの戦略をサポートしています。これら 3 つのタイプのサーキット ブレーカー ルールは次のとおりです。詳細な説明は、ページ構成と API 構成の 2 つの形式で提供されます。

1. 遅いコール率のヒューズページ

スローコール率とは文字通り、リクエスト総数に対するスローコールの割合に基づくサーキットブレーカーのことを指します。ページ構成を使用する場合の注意点は次のとおりです。

  • ページでサーキット ブレーカー ルールを構成する場合、メソッドに @SentinelResource アノテーションを追加する必要はありません。追加しない場合は、デフォルトのダウングレード メソッドを使用します。
  • ページで構成されたサーキット ブレーカー ルールは、ダッシュボードが再起動されるかターゲット サービスが再起動されるかに関係なく消えます。

次に、低速通話率のサーキット ブレーカー ルールを構成するには、まず「クラスター ポイント リンク」ページに入る必要があります (クラスター ポイント リンクは、実際にはリクエストを生成したインターフェイスであり、Sentinel のリソースです)。ご覧
ここに画像の説明を挿入します
のとおり、上記は設定を追加していないスクリーンショットですが、この時点で、[サーキット ブレーカー] をクリックしてサーキット ブレーカー ルールを追加できます。
ここに画像の説明を挿入します
上の図は、低速コール率サーキット ブレーカー ルールの構成ページです。合計 5 つのビジネス パラメータ (低速コール率を除く) が表示されます。

  • 最大 RT: ミリ秒単位、インターフェイスの最大応答時間この時間を超えると、呼び出しが遅いとみなされます。
  • 比率のしきい値: 低速通話リクエストの数/リクエストの総数、最大許容値
  • メルトダウン期間: ヒューズをトリガーした後、インターフェイスまたはリソースがヒューズ状態になるまでの時間
  • 最小リクエスト数: 同時リクエストの数。同時リクエストの数がこの数に達した場合にのみ低速通話率が計算され、しきい値に達するとサーキット ブレーカーがトリガーされます。
  • 統計期間: 同時リクエストの数をカウントする時間

上記のように、次のような設定が可能です。設定の意味は次のとおりです。
1 秒間の同時リクエスト数が 3 に達したかどうかをカウントします。3 に達した場合は、最大 RT に基づいて、これらのリクエストのうち遅い呼び出しの割合を計算します。割合を計算した後、割合のしきい値と比較します。しきい値に達した場合は、 、サーキット ブレーカーがトリガーされます。サーキット ブレーカー時間は 10 秒です。10 秒以内では、すべてのリクエストはメソッドには入りませんが、直接ダウングレード メソッドに入ります。ここでダウングレード メソッドが宣言されていない場合、デフォルトのダウングレード メソッドに入ります。サーキットブレーカー時間が経過すると、次のリクエストが成功すると計算が再開され、失敗すると直接サーキットブレーカーに再度入ります。
ここに画像の説明を挿入します
上記の構成が完了したら、[サーキット ブレーカー ルール] メニューで構成したばかりのサーキット ブレーカー ルールを確認して
ここに画像の説明を挿入します
テストできます。ここでは、低速通話をシミュレートする必要があります。100 以内の乱数を生成し、スリープすることができます。遅い通話をシミュレートします。

    @RequestMapping("/addStock")
    public void addStock() throws Exception{
    
    
        log.info("add stock start: {}",name);

        // 随机休眠100ms以内的时间-用于测试: 熔断规则-慢调用
        String s = String.valueOf(Math.floor(Math.random() * 100));
        Thread.sleep(Integer.parseInt(s.split("\\.")[0]));

    }

次に、トリガーの結果を確認します。
ここに画像の説明を挿入します
これは、デフォルトのダウングレード メソッドの戻りです。
上記の例では @SentinelResource を使用しておらず、ダウングレード方法も指定していません。@SentinelResource の使用と、同時にダウングレード方法を指定する方法について説明します。@SentinelResource を使用してダウングレード メソッドを指定することも前のセクションで説明しましたが、fallback または fallback+fallbackClass を直接使用してダウングレード メソッドを指定することもできます。ここでは、@SentinelResource の別の属性値も使用する必要があります。この属性の機能は、メソッドを Sentinel のリソースとして登録することです。Java コードは次のとおりです (@SentinelResource を使用する場合は、ダウングレード方法を指定する必要があります。このアノテーションを使用する必要があり、システムはデフォルトのダウングレード方法を使用しません。):

	// 使用注解,表明Sentinel资源,同时指明降级方法
    @SentinelResource(
            value = "addStock",
            fallback = "addStockFallback",
            fallbackClass = StockDefaultDegrade.class,
            exceptionsToIgnore = ArithmeticException.class)
    @RequestMapping("/addStock")
    public void addStock() throws Exception{
    
    
        log.info("add stock start: {}",name);

        // 随机休眠100ms以内的时间-用于测试: 熔断规则-慢调用
        String s = String.valueOf(Math.floor(Math.random() * 100));
        Thread.sleep(Integer.parseInt(s.split("\\.")[0]));
    }

ダウングレードメソッドのコードは次のとおりです。

@Slf4j
public class StockDefaultDegrade {
    
    

    /**
     * 这是fallback用的指定降级方法
     * @param throwable
     */
    public static void addStockFallback(Throwable throwable){
    
    
        log.info("触发addStockFallback的降级方法:" + throwable.getMessage() + " ");
    }
}

ページ構成ルールは、次のように、デフォルトのダウングレード方法が最後に使用されたときと同じです。ダウングレード方法を
ここに画像の説明を挿入します
再度開始すると、デフォルトのダウングレード削除は行われず、独自のダウングレード方法を入力します。
ここに画像の説明を挿入します

特記事項: ここで赤いボックスでマークされているもののみが、サーキット ブレーカーの開始時に実際に実行されるダウングレード メソッドです。ここで取得された例外はすべて null であることがわかります。サーキット ブレーカーの後、リクエストは直接ダウングレード メソッドに入ります。この時点では、メソッドはエラーを報告しないため、ここには null が入ります。このとき、メソッド内でランダムに例外がスローされた場合、例外を出力するダウングレード メソッドである必要があります。ただし、サーキット ブレーカーによってトリガーされるものではありません。サーキット ブレーカーによってトリガーされるダウングレード メソッドが低速呼び出し率、例外の数、または例外率のいずれであっても、その例外情報は null である必要があります。これは、メソッド例外によってトリガーされたダウングレードなのか、サーキット ブレーカー トリガーによってトリガーされたダウングレードなのかを区別するためにも使用できます。

1. 低速コール率サーキット ブレーカー API

上記では、ダッシュボードを使用して低速呼び出し率のサーキット ブレーカー、SentinelResource アノテーションを使用しない場合のダウングレード、およびカスタム ダウングレード メソッドのサーキット ブレーカーを構成する方法を紹介しました。API を使用してサーキット ブレーカーを構成する方法は次のとおりです。ほとんどの実際のシナリオでは、引き続き API が構成に使用され、特別なシナリオではダッシュボードで調整されます。API を使用するときは、次の問題に注意してください。

  • API を使用してサーキット ブレーカーを構成する場合、ダッシュボードを使用する必要はまったくありません。ダッシュボードを使用する目的は、API 構成の結果をより明確に確認することです。
  • サーキット ブレーカー ルールを構成するには、リソース名とサーキット ブレーカー ポリシーを設定し、パラメーターを構成し、ルール マネージャーにルールを送信するという 3 つの手順が必要です。
  • API で設定されたサーキット ブレーカーを使用します。ダッシュボードを使用する場合は、ダッシュボードの起動後にルールを確認できます。
  • API で設定したサーキット ブレーカーを使用してダッシュボードを変更することもでき、変更は有効になりますが、サービスまたはダッシュボードを再起動すると無効になります。
  • 最後に、管理のためにオブジェクトを Spring コンテナに渡すことを忘れないでください。

ダウングレードメソッドとインターフェースメソッドのコードは上記と同じなので割愛します スローコール率サーキットブレーカールールの設定はこちら 比較しやすいように3つの書き方を紹介します3 つの書き方の違い. 実際、これらはすべて 3 つのステップが必要ですが、後の 2 つのステップの 2 番目のステップにはパラメータが 4 つしかなく、他のステップには違いはありません。

/**
 * @author pcc
 * 三种熔断规则不可以同时设置到一个资源上,若是同时作用到一个资源上,最后加载的规则会覆盖之前的规则
 * 最终只有一个生效
 */
@Configuration
public class FuseConfig {
    
    

    // 熔断规则-慢调用比例
    @Bean
    public DegradeRule degradeRule(){
    
    
        DegradeRule degradeRule = new DegradeRule();
        // 资源名,资源名是唯一的
        degradeRule.setResource("addStock");
        // 熔断策略-0 慢调用比例 ,1 异常比例 ,2 异常数
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT);

        // 熔断时长,单位为 s
        degradeRule.setTimeWindow(10);
        // 触发熔断的最小请求数,需要配合下面的时间一起,默认5
        degradeRule.setMinRequestAmount(3);
        // 触发熔断的最小请求数的单位时间ms默认1000ms(这个时间内请求数达到最小请求,才会进行计算时间超过阈值的请求,然后计算比例,比例达到后才会进行熔断)
        degradeRule.setStatIntervalMs(1000);
        // 慢调用比例模式下为慢调用临界 RT,单位ms(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
        degradeRule.setCount(40);
        // 慢调用比例阈值默认1.0,sentinel1.8.0加入,0.0-1.0 之间
        degradeRule.setSlowRatioThreshold(0.2);


        // 将熔断规则交给熔断规则管理器
        List<DegradeRule> rules = new ArrayList<DegradeRule>();
        rules.add(degradeRule);
        DegradeRuleManager.loadRules(rules);

        return degradeRule;
    }


    // 熔断规则-异常比例
    @Bean
    public DegradeRule exceptionRatioRule(){
    
    
        DegradeRule degradeRule = new DegradeRule();
        // 该熔断规则对应资源名
        degradeRule.setResource("addStock");
        // 熔断策略-异常比例
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);

        // 异常比例阈值20%
        degradeRule.setCount(0.2);
        // 熔断时间单位s
        degradeRule.setTimeWindow(10);
        //  触发熔断的最小请求数,需要配合下面的时间一起,默认5
        degradeRule.setMinRequestAmount(3);
        // 触发熔断的最小请求数的单位时间ms默认1000ms(这个时间内请求数达到最小请求,才会进行计算时间超过阈值的请求,然后计算比例,比例
        degradeRule.setStatIntervalMs(1000);


        // 将熔断规则交给熔断规则管理器-这里可以使用单例集合,因为无论在哪里声明的规则都是要交给管理器的
        // 即使在这里将别的规则也加载了也没问题,所以可以使用单例集合
        DegradeRuleManager.loadRules(Collections.singletonList(degradeRule));
        return degradeRule;
    }

    // 熔断规则-异常数
    @Bean
    public DegradeRule execptionCountRule(){
    
    
        DegradeRule degradeRule = new DegradeRule();
        // 熔断资源
        degradeRule.setResource("addStock");
        // 熔断策略-异常数
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);

        // 异常数的阈值
        degradeRule.setCount(2);
        // 熔断触发最小请求数
        degradeRule.setMinRequestAmount(3);
        // 熔断最小请求书的统计时长,默认1000ms
        degradeRule.setStatIntervalMs(1000);
        // 熔断时间
        degradeRule.setTimeWindow(10);


        // 将熔断规则交给熔断规则管理器-这里可以使用单例集合,因为无论在哪里声明的规则都是要交给管理器的
        DegradeRuleManager.loadRules(Collections.singletonList(degradeRule));
        return degradeRule;
    }
}

結果が上記と変わらない場合は、再度投稿しません。

2. サーキットブレーカーの異常な割合 - ページ

ページの構成が若干異なる以外は、低速通話率のページ構成と同じです。
ここに画像の説明を挿入します
ページも分かりやすく、異常比率のしきい値を設定するもので、しきい値に達するとサーキットブレーカーが作動し、その後すべてのダウングレードメソッドが実行されます。ここで確認するには、ランダム性に基づいて例外を直接実行します。次の Java コードです。

    /**
     * 这里同时使用了fallback 、defaultFallback
     * 当同时使用时,只有fallback生效
     *
     */
    @SentinelResource(
            value = "addStock",
            defaultFallback = "stockDefaultFallback",
            fallback = "addStockFallback",
            fallbackClass = StockDefaultDegrade.class,
            exceptionsToIgnore = ArithmeticException.class)
    @RequestMapping("/addStock")
    public void addStock() throws Exception{
    
    
        log.info("add stock start: {}",name);

        // 随机休眠100ms以内的时间-用于测试: 熔断规则-慢调用
        String s = String.valueOf(Math.floor(Math.random() * 100));
        Thread.sleep(Integer.parseInt(s.split("\\.")[0]));

        // 随机产生异常用于测试:熔断规则-异常比例/异常数
        if(Integer.parseInt(s.split("\\.")[0])>50){
    
    
            throw new RuntimeException("运行异常哈");
        }

    }

このように、リクエストの一定の割合で RuntimeException がスローされますが、重要な点は、リクエストが十分に高速であれば、サーキット ブレーカーがトリガーされるということです。発動後は変化なし。ここで使用されるダウングレード方法は 1 つだけです (同じリソースに使用できるダウングレード方法は 1 つだけです)。

2. サーキットブレーカー API の異常な割合

ここで言及する必要があるのは setCount メソッドであり、他に言うことはありません。この方法は 3 つのサーキット ブレーカー戦略で利用できますが、その意味は異なるため、特別な注意が必要です。RT では、遅い呼び出しの継続時間を表す単位は ms です。例外率では、単位なしの例外率を表します。値は 0.0 ~ 1.0 の間です。例外数では、例外の数を表します。他のものについては特に言うことはありません。ここに 3 つの API のすべてのコードを示します。

/**
 * @author pcc
 * 三种熔断规则不可以同时设置到一个资源上,若是同时作用到一个资源上,最后加载的规则会覆盖之前的规则
 * 最终只有一个生效
 */
@Configuration
public class FuseConfig {
    
    

    // 熔断规则-慢调用比例
    @Bean
    public DegradeRule degradeRule(){
    
    
        DegradeRule degradeRule = new DegradeRule();
        // 资源名,资源名是唯一的
        degradeRule.setResource("addStock");
        // 熔断策略-0 慢调用比例 ,1 异常比例 ,2 异常数
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_RT);

        // 熔断时长,单位为 s
        degradeRule.setTimeWindow(10);
        // 触发熔断的最小请求数,需要配合下面的时间一起,默认5
        degradeRule.setMinRequestAmount(3);
        // 触发熔断的最小请求数的单位时间ms默认1000ms(这个时间内请求数达到最小请求,才会进行计算时间超过阈值的请求,然后计算比例,比例达到后才会进行熔断)
        degradeRule.setStatIntervalMs(1000);
        // 慢调用比例模式下为慢调用临界 RT,单位ms(超出该值计为慢调用);异常比例/异常数模式下为对应的阈值
        degradeRule.setCount(40);
        // 慢调用比例阈值默认1.0,sentinel1.8.0加入,0.0-1.0 之间
        degradeRule.setSlowRatioThreshold(0.2);


        // 将熔断规则交给熔断规则管理器
        List<DegradeRule> rules = new ArrayList<DegradeRule>();
        rules.add(degradeRule);
        DegradeRuleManager.loadRules(rules);

        return degradeRule;
    }


    // 熔断规则-异常比例
    @Bean
    public DegradeRule exceptionRatioRule(){
    
    
        DegradeRule degradeRule = new DegradeRule();
        // 该熔断规则对应资源名
        degradeRule.setResource("addStock");
        // 熔断策略-异常比例
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);

        // 异常比例阈值20%
        degradeRule.setCount(0.2);
        // 熔断时间单位s
        degradeRule.setTimeWindow(10);
        //  触发熔断的最小请求数,需要配合下面的时间一起,默认5
        degradeRule.setMinRequestAmount(3);
        // 触发熔断的最小请求数的单位时间ms默认1000ms(这个时间内请求数达到最小请求,才会进行计算时间超过阈值的请求,然后计算比例,比例
        degradeRule.setStatIntervalMs(1000);


        // 将熔断规则交给熔断规则管理器-这里可以使用单例集合,因为无论在哪里声明的规则都是要交给管理器的
        // 即使在这里将别的规则也加载了也没问题,所以可以使用单例集合
        DegradeRuleManager.loadRules(Collections.singletonList(degradeRule));
        return degradeRule;
    }

    // 熔断规则-异常数
    @Bean
    public DegradeRule execptionCountRule(){
    
    
        DegradeRule degradeRule = new DegradeRule();
        // 熔断资源
        degradeRule.setResource("addStock");
        // 熔断策略-异常数
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_COUNT);

        // 异常数的阈值
        degradeRule.setCount(2);
        // 熔断触发最小请求数
        degradeRule.setMinRequestAmount(3);
        // 熔断最小请求书的统计时长,默认1000ms
        degradeRule.setStatIntervalMs(1000);
        // 熔断时间
        degradeRule.setTimeWindow(10);


        // 将熔断规则交给熔断规则管理器-这里可以使用单例集合,因为无论在哪里声明的规则都是要交给管理器的
        DegradeRuleManager.loadRules(Collections.singletonList(degradeRule));
        return degradeRule;
    }
}

3. 例外番号サーキット ブレーカー - ページと API


ここに画像の説明を挿入します
ここには大きな違いはなく、変更の量は上記に比べて非常にわずかです。個別に話す価値はありません。まとめて見てください。以下は設定ページの内容です。異常な比率を変更しただけで、APIの書き方からも異常になっています。異常割合の割合閾値と異常数の例外数はともにcountで表されます。したがって、API の違いはサーキット ブレーカー戦略の違いとなりますが、ここでは繰り返し説明しません。

4. その他の重要なポイントを追加する

4.1 @SentinelResource アノテーションを追加した後、デフォルトのダウングレードは有効になりません。

この問題は上記で説明したとおりであり、実際に @SentinelResource アノテーションを使用しない場合、サーキット ブレーカーがトリガーされるとデフォルトのダウングレード メソッドが使用されますが、このアノテーションを追加した後は、ダウングレード メソッドを宣言する必要があります。そうでない場合は、システムのデフォルトのダウングレード方法を経由せずに、レポート 500 が報告されます。もちろん、実際のシナリオでは、ダウングレードの代わりにサーキット ブレーカーを使用する人はいないため、機能を検証する場合にのみ注意する必要があります。

4.2 統合ダウングレード処理

上記のデフォルトのダウングレード方法は、実際には Sentinel によって提供される統合例外処理です (グローバル例外ハンドラーに似ています)。これは変更することもでき、この統合例外処理を使用して戻り情報を指定したり、ページを返したりすることもできます。指定した Web サイトまたは静的リソースにリダイレクトできます。これは、デフォルトの統合ダウングレード処理方法です。
ここに画像の説明を挿入します

では、この統一された例外処理を自分たちで実装する場合、どうすればよいのでしょうか? 実際、次のように彼の書き方を参照するだけで済みます。

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.BlockExceptionHandler;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author pcc
 */
@Component
public class GlobalDegradeConfig implements BlockExceptionHandler {
    
    

    @Override
    public void handle(HttpServletRequest request, HttpServletResponse response, BlockException e) throws Exception {
    
    
        response.setStatus(429);
        response.setHeader("Content-Type", "application/json");
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write("{\"code\":429,\"msg\":\"请求过于频繁,请稍后再试\"}");
        response.getWriter().flush();
    }
}

検証も非常に簡単です。インターフェイス上の @SentinelResource アノテーションを削除し、ページ上のサーキット ブレーカー ルールを再構成するだけです。この時点でテストできます。結果は図に示すとおりです。
ここに画像の説明を挿入します

ただし、この統合されたダウングレード処理の使用には問題があります。つまり、この統合されたメソッドはサーキット ブレーカーによってトリガーされたダウングレード シナリオにのみ適用できるため、例外が発生したときにダウングレード メソッドが存在しない場合、そのダウングレード メソッドがユーザーに直接スローされます。 。したがって、この統合サーキット ブレーカーのダウングレード処理を使用することは依然として推奨されず、代わりに @SentinelResource を使用してダウングレード方法を指定します。このようにして、通常の例外を処理できないシナリオはなくなります。

4.3 BLockException をスローしてもサーキット ブレーカー ルールはトリガーされません

このシナリオは実際のビジネス シナリオではめったに発生しませんが、例外比率と例外数のサーキット ブレーカー戦略を使用し、コード内でスローされるものが BlockException クラスの子である場合、自分でテストする場合に発生する可能性があります。例外 (5 つのルールに対応する例外) は、サーキット ブレーカー ルールを正常にトリガーできません。興味があれば検証してみると良いでしょう。

4.4 配置spring.cloud.sentinel.eager:true

Sentinel ローディング サービスのスターベーション モードをオンにします。デフォルトでは、Sentinel はサービス インターフェイスが呼び出された後にのみターゲット サービスをロードします。スタベーション ローディングをオンにすると、サービスは開始時に直接ロードされます。ただし、リクエストが来ない場合はサービスがロードされます。 、「リアルタイム監視」でロードしますが、データはまだ「クラスターポイントリンク」に表示されません。

5. 電流制限フロー制御ルール: FlowRule

電流制限とサーキット ブレークは、Sentinel の 2 つの最も重要なルールです。サーキット ブレーカーは、異常なシナリオでのサービスの正しい復帰を保証し、フロー制御は、高い同時実行下でのサービスの安定性を保証します。私たちは、サービスが確実に機能するように、適切なフロー制御戦略を設定します。同時実行性が高いシナリオでも圧倒されることはありません。
サーバーを無制限に拡張できる企業は存在しないと考えられるため、限られたサーバーリソースの中で、サーバークラスターで許容される同時実行数を超えるリクエストをどのように処理するかを検討する必要があり、その際にフロー制御を使用する必要があります。ルールです。Sentinel フロー制御ルールは、タイプに応じて、QPS (1 秒あたりのクエリ数) と同時スレッド数 (同時スレッドの数は TPS と見なすことができます) の 2 つの主要なカテゴリをサポートします。これらは、現在最も人気のある 2 つのソリューションでもあります。違いがある場合は、以下で詳しく説明します。
1.
これは、Sentinel ダッシュボードのフロー制御ルール設定のページです。以下の内容が含まれており、一見すると各パラメータの組み合わせシナリオがたくさんあるように感じられますが、実際にはしきい値の種類とクラスターに重点を置くことができます。特別なニーズがあるシナリオがある場合は、フロー制御モードと効果の設定を検討できます。

  • リソース名: Sentinel に登録されているリソースは @SentinelResource を使用して宣言する必要があります
  • ソースの場合: Sentinel は、さまざまなソースのフロー制御をサポートしています。たとえば、私はサービス プロバイダーであり、Baidu、Alibaba、および Tencent はすべて私のサービスを使用しています。私は Tencent に対してのみフロー制御ルールを設定します。現時点では、この属性を使用できます。ただし、QPS と同時スレッド数の両方がソース固有をサポートしているため、これにはコードへの変更が必要になります (これについては別途説明します)。
  • しきい値タイプと単一マシンしきい値: これらは Sentinel でサポートされる 2 つのルールです
  • クラスタ化するかどうか: サービスは基本的にクラスタ化されているため、これは基本的に必須の選択となります。ただし、クラスタ モードでは単一マシンか全体のしきい値を設定する必要があります。これについても、QPS と数が異なるため、別途説明します。の同時スレッドの両方がサポートされます。
  • フロー制御モード: クラスター モードではサポートされません。ここでは、直接、関連付け、およびリンクの設定がサポートされます。QPS と同時スレッド数の両方がサポートされます。詳細は別途紹介します。
  • フロー制御効果: クラスター モードではサポートされていません。QPS のみがサポートしています。高速フェイル、ウォーム アップ、キュー待機が選択できます。これについては、別途紹介します。

前述のように、一部の構成では QPS がサポートされており、同時スレッドの数を設定できます。このパラメーターは、ソース、クラスター、フロー制御モードなどのシナリオの 1 つを使用してのみ説明されます。

1.QPSフロー制御ページ

フロー制御ルールを宣言した後、フォールバックで宣言されたダウングレード メソッドを使用する場合、サーキット ブレーカーであってもフロー制御であっても、フォールバックのダウングレード メソッドが呼び出されることに注意してください。サーキット ブレーカーまたはフロー制御の場合、フォールバックのダウングレード メソッドが呼び出されます。フロー制御のためにブロックハンドラー メソッドが引き続き呼び出されます。もちろん、ブロックハンドラーの通常のダウングレードでもフォールバックが使用されることが宣言されています。もう 1 つの注意点は、溶断と電流制限を同時に宣言する場合、まず溶断が溶断しているかどうかを判断する必要があり、すでに溶断されている場合には電流制限は適用されません。

  • 1. フォールバックを使用して、ダウングレード、サーキット ブレーカー、フロー制御などを処理するダウングレード メソッドを宣言します。
    ページでフロー制御ルールを構成する場合は、まず管理のためにメソッドを Sentinel に引き渡す必要があります。ダウングレード、サーキット ブレーカー、またはフロー制御のいずれであっても、そのダウングレード メソッドを宣言します。フロー制御は通常、フォールバック メソッドに入ることができます。
    これは Sentinel によって管理されるリソース コードです。
package com.cheng.stockserver.flowrule.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.cheng.stockserver.flowrule.degradeclass.BlockMethod;
import com.cheng.stockserver.flowrule.degradeclass.DegradeMethod;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author pcc
 * 正常情况下sentinel应该使用在customer端,而不是server端,这里只是测试一下就无所谓了
 */
@Slf4j
@RestController
@RequestMapping("/flow")
public class controller {
    
    

    @Value("${name}")
    String name;

    @RequestMapping("/testFlowRule")
    @SentinelResource(
            value = "testFlowRule",
            fallback = "testFlowRule", // 降级配置
            fallbackClass = DegradeMethod.class
    )
    public String testFlowRule(){
    
    

        log.info("testFlowRule start, name : {}",name);

        // 产生一个100以内的随机数
        int i = Integer.parseInt(String.valueOf(Math.random() * 100).split("\\.")[0]);

        // 当随机数大于60时,抛出异常(值越大抛出异常概率越小) 方便验证降级、熔断
        if(i>60){
    
    
            throw new RuntimeException("testFlowRule error");
        }

        return "success";
    }

}

これは宣言されたフォールバック メソッドです。ここで Throwable の実際の型を出力して、どのシナリオがメソッドをトリガーしたかを確認します。ダウングレード、サーキット ブレーカー、フロー制御などであり、例外クラスによって区別できます。

import lombok.extern.slf4j.Slf4j;

/**
 * @author pcc
 */
@Slf4j
public class DegradeMethod {
    
    

    public static String testFlowRule(Throwable th){
    
    
        log.info("触发降级方法: {},异常:{}",th.getMessage(),th.getClass().getName());
        return "降级方法返回:success";
    }
}

サーキット ブレーカー ルールの設定と上記の設定に違いはありません。ここでは異常比率を使用してサーキット ブレーカー ルールを設定します。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRule;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.ArrayList;
import java.util.List;

/**
 * @author pcc
 */
@Configuration
public class DegradeConfig {
    
    

    /**
     * 如果有多个熔断规则应该这么写
     * 或者是使用一个单例list,把所有的熔断规则都放进去,最后一次交给
     * 熔断规则管理器
     * @return
     */
    @Bean
    public DegradeRule getDegradeRule() {
    
    

        List<DegradeRule> lists = new ArrayList<DegradeRule>();

        /**
         * 这是第一个熔断规则,支持多个规则的配置
         */
        // 这里使用熔断规则的异常比例规则来处理降级
        // 使用异常比例更容易看到是普通降级还是熔断导致的降级(看异常信息有没有值就知道了)
        DegradeRule degradeRule = new DegradeRule();
        // 声明熔断对应的资源、sentinelresource中value声明
        degradeRule.setResource("testFlowRule");
        // 降级策略使用异常比例
        degradeRule.setGrade(RuleConstant.DEGRADE_GRADE_EXCEPTION_RATIO);

        // 设置降级规则
        degradeRule.setCount(0.5); // 20%的异常会熔断
        degradeRule.setTimeWindow(10); // 熔断10s
        degradeRule.setMinRequestAmount(2);// 最小请求数
        degradeRule.setStatIntervalMs(1000);// 最小请求数的统计时间1s

        // 将降级规则交由熔断管理器
        // 以上配置,1s内有两次请求,其中只要有一个异常就会熔断10s
        lists.add(degradeRule);

        DegradeRuleManager.loadRules(lists);

        return degradeRule;
    }
}

融合に必要なのはこれだけで、実は以前紹介したものなのですが、ここでは融合とフロー制御を同時に設定した場合の効果を実証するのが主な目的なので、融合の設定を再度行う必要があります。フロー制御は、ページを使用してここで構成されます。構成したばかりのサーキット ブレーカー ルールのリソース testFlowRule を構成し、次のようにフロー制御ルールを構成します: このルールを構成した後、QPS が 3 を超えるリクエストは直接フォールバックに入り
ここに画像の説明を挿入します
ますこの方法では、QPS が 3 つを超えない限り、リクエストは通常​​どおりリソースに入ることができます。以下は実行中のスクリーンショットです。
ここに画像の説明を挿入します
ダウングレード方法には、ダウングレード出力、フロー制御出力、およびヒューズ出力の 3 つの出力があることがわかります。ここでは、サーキット ブレーカーとダウングレードが同時にリソースに適用された場合の効果を確認できます。①. フォールバックは、ダウングレード、サーキットブレーカー、フロー制御などのシナリオを同時に処理できる. 内部的には、instanceof を使用して例外クラスを決定し、さまざまな処理を実装することができます

②.
リソースにサーキット ブレーカーとフロー制御が同時に設定されている場合、フロー制御ルールのトリガーには、リソースがサーキット ブレーカーにならず、サーキット ブレーカー中にフロー制御が正常にトリガーできないという前提が必要です。これも合理的であり、リソースが異常であればアクセスする必要がなく、アクセスがなければフロー制御も必要ない。通常のリクエストは次のようになります。
ここに画像の説明を挿入します

リクエストが来ると、まずリソースがサーキットブレーカーかどうかを確認し、サーキットブレーカーであればサーキットブレーカーのメソッドを実行します。フォールバックで指定したメソッドはこちらです。サーキットブレーカーが無い場合のみ判定します。フロー制御を行うかどうか。フロー制御がない場合は、リソースを入力できます。

  • 2. ブロックハンドラーを使用して、ダウングレード メソッドを宣言します。
    フォールバックは、サーキット ブレーカーとフロー制御を示すために上記で使用されています。SentinelResource は、サーキット ブレーカーやフロー制御などの 5 つのルール シナリオを特に処理するためのブロックハンドラーも提供します。したがって、最良の方法は、フォールバックを使用しないことです。フロー制御を処理するため、サーキット ブレーカーを使用する代わりにブロックハンドラーが使用され、フォールバックはダウングレードの処理に特に使用されます。ブロックハンドラーの使用とフォールバックの使用に違いはありません。上記のフォールバックを使用したコード全体との違いは、ブロックハンドラーの構成を追加するだけで済み、残りは上記と完全に一致することです。以下は、リソース内の新しい構成のコードであり、変更点のみを示しています。
    @RequestMapping("/testFlowRule")
    @SentinelResource(
            value = "testFlowRule",
            fallback = "testFlowRule", // 降级配置
            fallbackClass = DegradeMethod.class,
            blockHandler = "testFlowRule", // 流控配置:配置熔断规则时若是增加了blockhandler,则熔断时进入的是该方法而不是fallback
            blockHandlerClass = BlockMethod.class
    )

以下はフロー制御メソッドの実装です。このメソッドは BlockException を渡す必要があり、そうでない場合は有効になりません。これは必須の要件です。, メソッド内では、実際の例外タイプに基づいて、どのシナリオがメソッドをトリガーしたかを判断できます。

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.degrade.DegradeException;
import com.alibaba.csp.sentinel.slots.block.flow.FlowException;
import lombok.extern.slf4j.Slf4j;

/**
 * @author pcc
 */
@Slf4j
public class BlockMethod {
    
    

    /**
     * 流控方法这里必须声明BlockException的,不然是无法进入流控方法的
     * 流控也不会生效
     * @param blockException 流控异常
     * @return
     */
    public static String testFlowRule(BlockException blockException){
    
    

        /**
         * 这里异常时没有异常信息的,只能通过异常的类型来判定是熔断还是流控等
         */
        if(blockException instanceof DegradeException){
    
    
            // 处理熔断
            log.info("block-熔断-方法: {}","DegradeException");
            return "block-熔断-方法返回:success";
        }
        if(blockException instanceof FlowException){
    
    
            // 处理流控
            log.info("block-流控-方法: {}","FlowException");
            return "block-流控-方法返回:success";
        }

        return "block方法返回:success";
    }
}

他のコードはフォールバックを使用する上記の例とまったく同じであるため、ここでは再度表示しません。次に、この時点でインターフェイスをトリガーした結果を見てください: 上の図から、サービスの低下がまだ発生していることがわかります
ここに画像の説明を挿入します
。フォールバックを使用しており、サーキット ブレーカーとフロー コントロールにブロックハンドラーが追加されています。将来的にはフォールバックは使用されず、ブロックハンドラーで指定されたメソッドが使用されます。

1.QPSフロー制御API

ここでのコードと変更は、上記のシナリオでのブロックハンドラーの使用に基づいており、次の構成が追加されています。実際には、ページ上の構成ルールがコードに組み込まれており、それ以外は何も変更されません。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
 * @author pcc
 */
@Configuration
public class FlowConfig {
    
    

    @Bean
    public FlowRule getFlowRule() {
    
    
        FlowRule flowRule = new FlowRule();
        // 声明流控的资源
        flowRule.setResource("testFlowRule");
        // 声明使用的流控规则:0 并发线程数,1 QPS
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);

        // 流控规则设置-QPS阈值2
        flowRule.setCount(2);
        // 来源没有默认值,必须手动设定,default表示对所有来源生效
        flowRule.setLimitApp("default");


        // 将流控规则交给流控管理器
        FlowRuleManager.loadRules(Collections.singletonList(flowRule));
        return flowRule;
    }
}

上記の構成を追加した後、構成されたフロー制御ルールや以前のサーキット ブレーカー ルールさえもログイン ページに表示されなくなる場合があります。ただし、これらのルールはクライアントで通常どおり有効になります。次のように表示されます。
ここに画像の説明を挿入します
上記のダッシュボードのバグは、サーキット ブレーカー ルールやフロー制御ルールの有効性に影響を与えませんが、ルールがダッシュボードに表示されなくなることがあります (本番環境での直接使用にダッシュボードを推奨しなければならないのも不思議ではありません。多くのルールがあります)この問題を解決するのは実際には簡単です。まず、設定した FlowRule をコメントアウトして再起動し、次にコメントを解除して再起動してバイパスします。具体的な理由はわかりません。
検証内容は上記と変わりませんので、ここでは繰り返しません。

2. 同時スレッド数 - ページ/API

QPS ベースのフロー制御は、単位時間あたりのリクエスト数をカウントするだけで理解できるはずです。さらに、Sentinel はフロー制御のための同時スレッドの数もサポートしています。同時スレッド数は、Hystrix によって最初に提供されました。Hystrix では、同時スレッド数について 2 つの実装方法 (スレッド プール分離とセマフォ分離) を提供しています。スレッド プールの分離とは、リソースにスレッド プールを事前に割り当てることです。指定されたリソースは、指定されたスレッド プールのスレッドのみを使用でき、フロー制御は枯渇します。セマフォ分離では、入ってくるスレッドの総数のみがカウントされます。総数に達したら、フローを制御します。Sentinel の同時スレッド ソリューションは、2 つ (スレッド プールの分離、セマフォの分離) を統合したものと同等です。Sentinel は、要求スレッドと実行スレッドを分離するという点でスレッド プールの分離に似ています。セマフォと同様に、Sentinel はスレッドの総数をカウントします (この量は実行スレッドの数である必要があります)。スレッドの数がフロー制御に達すると、Sentinel はスレッドの総数をカウントします。

次に、同時スレッド データのページ構成を見てみましょう:
ここに画像の説明を挿入します
ここに画像の説明を挿入します
同時スレッド数のフロー制御をトリガーするには、ここのリソース コードを少し調整する必要があります。プログラムを手動でしばらくスリープ状態にする必要があります。同時スレッドの数を増やすと、リクエストは受信時にブロックされます。処理後、トリガーするのは困難です (スリープ時間がヒューズの統計時間を超えると、ヒューズはトリガーされないことに注意してください)。

上記がページの構成ですが、APIも非常にシンプルで、グレードを変更するだけで、その他の構成はQPSと全く変わりません。他のコードは上記と同じで、次のようにページ設定を API に移行します。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
 * @author pcc
 */
@Configuration
public class FlowConfig {
    
    

    @Bean
    public FlowRule getFlowRule() {
    
    
        FlowRule flowRule = new FlowRule();
        // 声明流控的资源
        flowRule.setResource("testFlowRule");
        // 声明使用的流控规则:0 并发线程数,1 QPS
        flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD);

        // 流控规则设置-线程并发阈值2
        flowRule.setCount(2);
        // 来源没有默认值,必须手动设定,default表示对所有来源生效
        flowRule.setLimitApp("default");


        // 将流控规则交给流控管理器
        FlowRuleManager.loadRules(Collections.singletonList(flowRule));
        return flowRule;
    }
}

注:
QPS と同時スレッドの数は、一部のシナリオでは同様の影響を及ぼしますが、ほとんどのシナリオは異なります。どのように言って?
QPSとは、単位時間あたりに受信されるリクエストのことで、単位時間あたりの最大しきい値のリクエストを受信する限り、他のリクエストは受信できません。
同時スレッドの数は、現在のリクエストによって占有されているスレッドの数を強調します。1 秒以内に 3 つのリクエストが受信されるシナリオがあります。3 つのリクエストが QPS のしきい値であると仮定すると、QPS のフロー制御がトリガーされます。3これら 3 つのタスクを実行するために 3 つのスレッドが存在しますが、可能性は 2 つあります。① これら 3 つのリクエストのサーバー側の処理には 10 秒かかるため、この 10 秒以内に別のリクエストが受信された場合、フロー制御されますが、QPS は制御されません。これは、リクエストが受信されたかどうかによってのみ決まります。処理にどれくらい時間がかかりますか。② サーバーがこれら 3 つのリクエストを処理するのに要した時間はわずか 0.5 秒であるため、この 1 秒以内に最大 6 つのリクエストが受信される可能性があります。これは、QPS と同時スレッド数の差です。要約すると、QPS はインレット トラフィックに重点を置き、同時スレッドの数はリソース内の同時実行性に重点を置きます。

3. フロー制御モード - 関連付け (QPS を使用) - ページ/API

現実のシナリオではそのようなシナリオが存在するはずで、一部のコア インターフェイスは非アクティブ化してはなりませんが、一部のインターフェイスは短期間であれば問題なく非アクティブ化できます。
このシナリオでは、関連付けられたフロー制御モードを使用できます。いわゆる関連付けられたフロー制御モードは次のとおりです。フロー制御モードで関連付けを選択し、関連付けられたリソースを入力する必要があります。これにより、リソースにアクセスするときに addStock が表示されますQPS しきい値 2 に達すると、testFlowRule はフロー制御されます。
注: 逆にしないでください。最初の行で宣言されたリソースは、関連付けられたリソースへのアクセスが QPS しきい値に達するとフロー制御されます。
ここに画像の説明を挿入します
ここで確認するには、Jemter (他の http クライアント ツールも使用できます) を使用してスレッド グループを設定し、1 秒あたりのアクセス数が 2 を超える必要があります。次の設定を行います。
ここに画像の説明を挿入します

次に、addStock へのアクセス中、testFlowRule へのアクセスは、以下に示すようにフロー制御される必要があります。

(ここでの addStock インターフェースは通常のインターフェースと変わらないため、コードは掲載しません。Sentinel リソースとして登録し、リソース名が addStock であることを宣言する必要があることに注意してください。)
ここに画像の説明を挿入します
testFlowRule のアクセス要求は完全にフロー制御されます。この時点では addStock の QPS が 10 で、設定した 2 を超えているため、testFlowRule へのすべてのアクセスはフロー制御されます。

考えてみます: addStock がサーキット ブレーカーをトリガーした場合、testFlowRule は通常どおりフローを制御しますか?

addStock サーキット ブレーク中にシステム リソースが消費されないため、フロー制御すべきではありません。現時点では、フロー制御は意味がないため、フロー制御すべきではありません。実際には、フロー制御すべきかどうかを決定する上記のプロセスがあります。流量制御: まず、回路がサーキットブレーカーであるかどうかを判断します。当然、ヒューズは流量を制御しません。![ここに画像の説明を挿入](https://img-blog.csdnimg.cn/0b42ce80d90a457ab8494c08684294ff.png) 上記の出力メソッドから、testFlowRule は通常のデータであり、フロー制御されていないことがわかります。これも同様です期待を込めて。

-------------------------------------------------- ----------API 設定----------------------------- ------------------------------------------------
以上ページの使い方を紹介しました。API を使用して関連するフロー制御を設定する方法はすべて、次のように変更できます。他のコードに違いがない場合は、投稿しません。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
 * @author pcc
 */
@Configuration
public class FlowConfig {
    
    

    @Bean
    public FlowRule getFlowRule() {
    
    
        FlowRule flowRule = new FlowRule();
        // 声明流控的资源
        flowRule.setResource("testFlowRule");
        // 声明使用的流控规则:0 并发线程数,1 QPS
        flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD);

        // 流控规则设置-线程并发阈值2
        flowRule.setCount(2);
        // 来源没有默认值,必须手动设定,default表示对所有来源生效
        flowRule.setLimitApp("default");
        // 流控模式-关联
        flowRule.setStrategy(RuleConstant.STRATEGY_RELATE);
        // 流控模式-关联-资源
        flowRule.setRefResource("addStock");


        // 将流控规则交给流控管理器
        FlowRuleManager.loadRules(Collections.singletonList(flowRule));
        return flowRule;
    }
}

テストなどに違いはないので、ここでは繰り返しません。

4. フロー制御モード - リンク(同時使用スレッド数) - ページ/API

フロー制御リソースは通常インターフェイスに追加されますが、通常のメソッドに追加することもでき、インターフェイス A とインターフェイス B の両方が同時に同じリソースを呼び出す場合があります。ビジネス A がより重要で、ビジネス B がそれほど重要ではない場合、リソースが限られている場合、リソースを A に傾け、B のフローを制御できます。
このように考えると、リンク フロー制御はアソシエーション フロー制御に似ていますか? リンク フロー制御でできることは関連フロー制御でも可能ですが、関連フロー制御はさまざまなシナリオのリソースを対象とするのに対し、リンク フロー制御は同じリソースへのさまざまな入り口を制限することに重点を置いています。アソシエーション フロー制御とリンク フロー制御のもう 1 つの違いは、アソシエーション フロー制御 B のリソースがフロー制御 A のしきい値に達するのに対し、リンク フロー制御はリソース B がしきい値に達したときのフロー制御 B のソースの 1 つであることです。
リンク フロー制御を使用するには、次のように application.yml: spring.cloud.sentinel.web-context-unify=false に設定を追加する必要があります。

spring:
  application:
    # 阿里系的组件好像都会使用这个作为默认名称:nacos、sentinel
    name: stock-server # nacos配置中心和注册中心默认都是用这个作为默认名称
  cloud:
    sentinel:
      transport:
        port: 8719 # dashboard控制面版与sentinel通信的本地端口
        dashboard: 127.0.0.1:8088   # sentinel控制面板地址
      eager: true # 是否饥饿加载,默认为false,开启后启动项目就会初始化,而不是在第一次调用,dashboard也可以直接就可以看到服务,不用等待接口调用后才可以看到
      web-context-unify: false # 默认true,收敛资源访问的所有入口,若是想要使用链路流控,必须关闭
      

次のメソッド testChain があり、/testFlowRule1 および /testFlowRule2 インターフェイスによって同時に参照されます。testChainQPS または同時スレッドがしきい値に達したときに、/testFlowRule1 のフロー制御を設定します。コードは次のとおりです。

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.cheng.stockserver.flowrule.degradeclass.BlockMethod;
import lombok.extern.slf4j.Slf4j;

/**
 * @author pcc
 */
@Slf4j
@org.springframework.stereotype.Service
public class serviceImpl implements ChainService {
    
    


    @Override
    @SentinelResource(
            value = "testChain",
            blockHandler ="testChainFlow",
            blockHandlerClass = BlockMethod.class
    )
    public void testChain() {
    
    
        log.info("testChain start");
        // 使用并发线程数模拟流控-加大方法响应时间,提高线程并发数
        try {
    
    
            Thread.sleep(1000);
        } catch (InterruptedException e) {
    
    
            throw new RuntimeException(e);
        }

    }
}

また、フロー制御メソッドは静的メソッドを使用すること、戻り値は一貫性を持たせること、BlockException を宣言することなど、ブロックハンドラーを使用する際の規則に注意してください。フロー制御方法は次のとおりです。

    /**
     * 链路流控使用的流控方法
     */
    public static void testChainFlow(BlockException blockException) {
    
    

        if(blockException instanceof DegradeException){
    
    
            // 处理熔断
            log.info("链路流控-熔断-方法: {}","DegradeException");

        }
        if(blockException instanceof FlowException){
    
    
            // 处理流控
            log.info("链路流控-流控-方法: {}","FlowException");
        }

    }

ページに構成を追加します:
ここに画像の説明を挿入します
以下はテストのスクリーンショットです。testFlowRule1 インターフェイスによる testChain 呼び出しのみがフロー制御され、testFlowRule2 呼び出しはフロー制御されないことがわかります。
ここに画像の説明を挿入します
************************************************* * ********** 以下は APIj の紹介です******************************** **** ************************
API を使用することは、ページを使用することと同じです。唯一の変更点は、コードを使用してルールを構成することです。それ以外は同じです。変更点は次のとおりです: 表示コードと検証の間に違いはありません。API を使用するときに操作される属性と関連付けモードは同じです。次のように属性値を変更するだけです。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
 * @author pcc
 */
@Configuration
public class FlowConfig {
    
    

    @Bean
    public FlowRule getFlowRule() {
    
    
        FlowRule flowRule = new FlowRule();
        // 声明流控的资源
        flowRule.setResource("testChain");
        // 声明使用的流控规则:0 并发线程数,1 QPS
        flowRule.setGrade(RuleConstant.FLOW_GRADE_THREAD);

        // 流控规则设置-线程并发阈值2
        flowRule.setCount(3);
        // 来源没有默认值,必须手动设定,default表示对所有来源生效
        flowRule.setLimitApp("default");
        // 流控模式-链路
        flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN);
        // 流控模式-链路-路径
        flowRule.setRefResource("/flow/testFlowRule1");



        // 将流控规则交给流控管理器
        FlowRuleManager.loadRules(Collections.singletonList(flowRule));
        return flowRule;
    }
}

5. 流量制御効果-予熱-ページ/API

フロー制御効果のデフォルトは高速障害です (フロー制御効果をサポートしているのは QPS のみです)。高速障害では、指定したブロックハンドラー メソッドが呼び出されます。実際、QPS が瞬間的に増加すると、サーバーがサービスを直接過負荷にする可能性があります。ストレス テスト中は 100,000 の同時実行が許可されていますが、実際のビジネスでは、QPS が非常に低いレベルから 10w に低下すると、サービスに負荷がかかる可能性もあります。この時点では、予熱によるフロー制御効果の使用を検討できます。予熱流量制御は、予熱時間中に QPS をゆっくりと増加させ、システムに反応する時間を与え、システムが瞬間的なピークによって圧倒されないようにします。
このようなシナリオがある場合: 通常の状況では QPS が 10 で、突然 QPS が 1000 に達し、予熱モードを使用し、予熱時間が 10 秒の場合、Sentinel はフロー制御の QPS 値を 10 秒以内にゆっくりと増加させます。 100 QPS のみを受信し、他の受信は失敗します。2 秒目では 200 QPS を受信し、他の受信も失敗します。10 秒目では、1000 QPS を処理できます。このとき、ウォームアップは完成しました。
予熱モードには小さな欠点があります: 予熱期間中の QPS しきい値は、実際には設定した最大値ではなく、時間の経過とともに設定した最大値まで徐々に増加します。ページ構成は次のとおりです。
ここに画像の説明を挿入します

100 QPS は人間では達成できず、ツールを使用する必要があるため、テストにはここで Jemeter を使用する必要があります。上の図に示すように、testChain で予熱フロー制御を実行します。期待される効果: 最初に、いくつかのリクエストがフロー制御されるように求められます。10 秒後には、すべてのリクエストがフロー制御されなくなります (jemeter は同時実行性を次のように設定します) 100): ここには実際のスクリーンショットはありません
ここに画像の説明を挿入します
。Sentinel の予熱時間が 10 秒であることを除いて、効果は実際に予想したものに非常に近いです。その QPS しきい値は 10 秒以内に上昇しますが、これは線形ではありません。完了するまでに 10 秒もかからない場合があります。予熱は必要ですが、10 秒を保証できます。最終システムの QPS は 100 でなければなりません。基本的に、すべてのニーズを満たします。

************************************************* * ********** 以下は API の紹介です********************************* *************************
ページと比較すると、API は 2 行の設定を追加するだけで、非常にシンプルで他に追加するものはありません。違い:
注: 同時スレッドの数はフロー制御効果をサポートしていません。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
 * @author pcc
 */
@Configuration
public class FlowConfig {
    
    

    @Bean
    public FlowRule getFlowRule() {
    
    
        FlowRule flowRule = new FlowRule();
        // 声明流控的资源
        flowRule.setResource("testChain");
        // 声明使用的流控规则:0 并发线程数,1 QPS
        flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);

        // 流控规则设置-线程并发阈值2
        flowRule.setCount(100);
        // 来源没有默认值,必须手动设定,default表示对所有来源生效
        flowRule.setLimitApp("default");
        // 流控模式-链路
        flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN);
        // 流控模式-链路-路径
        flowRule.setRefResource("/flow/testFlowRule1");
        // 流控效果-预热
        flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_WARM_UP);
        // 流控效果-预热-预热时间: 10s
        flowRule.setWarmUpPeriodSec(10);


        // 将流控规则交给流控管理器
        FlowRuleManager.loadRules(Collections.singletonList(flowRule));
        return flowRule;
    }
}

6. フロー制御エフェクトキューイングページ/API

これがフロー制御効果です。列に並んで待っている場合、そのようなシナリオが存在する可能性があります。システムは 1,000 QPS までしか耐えられませんが、最大 QPS は 1,500 です。残りの 500 は瞬時には処理できませんが、ピークが長く続かなかったり、ピークと過小評価が交互に現れたりするため、現時点では最善の解決策です。キュー待機フロー制御効果を使用することです。キューイングの効果は、ピーク シェービングとバレー フィリングに似ています。つまり、瞬間的な高トラフィックがピーク シェービングであり、処理できないリクエストは、リクエストがあまりないときに処理に投入されます。もちろんリクエストが少なく処理できない場合もあり、その場合はフロー制御メソッドのブロックハンドラが実行されます。
ページの構成は次のとおりです:
ここに画像の説明を挿入します
上記の構成は、QPS が 100 を超えるリクエストが待機キューに入り、システムの実行を待機することを意味します。最大待機タイムアウトは 5000 ミリ秒です。5 秒経過しても処理されない場合、フローは制御メソッドが実行されます。ページ構成コードを使用する場合は何も変更する必要はありません。検証には jemeter の助けも必要です。同時実行数を 150 に設定して 1 回実行できます。システムがフロー制御メソッドを実行しない場合、リクエストが100を超える場合は通常通り処理され、キュー待機も有効になります。

ここに画像の説明を挿入します
ここでは写真の一部のみを撮影していますが、実際にはすべての情報が正常であり、設定した待機キューが完全に正常であることが証明されています。
************************************************* * ********** 以下は API の紹介です********************************* *** **********************
ページ構成と比較すると、唯一の変更点は、コードにフロー制御効果のキューイングと待機を追加することです。他に変更はありません。:

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
* @author pcc
*/
@Configuration
public class FlowConfig {
    
    

   @Bean
   public FlowRule getFlowRule() {
    
    
       FlowRule flowRule = new FlowRule();
       // 声明流控的资源
       flowRule.setResource("testChain");
       // 声明使用的流控规则:0 并发线程数,1 QPS
       flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);

       // 流控规则设置-线程并发阈值2
       flowRule.setCount(160);
       // 来源没有默认值,必须手动设定,default表示对所有来源生效
       flowRule.setLimitApp("default");
       // 流控模式-链路
       flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN);
       // 流控模式-链路-路径
       flowRule.setRefResource("/flow/testFlowRule1");
       // 流控效果-排队等待
       flowRule.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER);
       // 流控效果-排队等待-超时时间: 5s
       flowRule.setMaxQueueingTimeMs(5000);


       // 将流控规则交给流控管理器
       FlowRuleManager.loadRules(Collections.singletonList(flowRule));
       return flowRule;
   }
}

7. ソースに基づいた制御フロー

ソース固有のフロー制御は、フロー制御モードのリンク モードに似ていますが、動作する場所が異なります。ソースをターゲットにしたものが上位になります。このソースについては、リクエスト ヘッダー内のサービス呼び出し元と合意できます。その後、特定のソースに対してフロー制御を実行できます。前述のフロー制御モードのリンクは、異なるインターフェース上で同じリソースを呼び出す際にサービス内で行われるフロー制御ですが、もちろん、リンクモードを使用して、異なるソースを提供するだけでソース制御と同じ効果を実現することもできます。異なる倉庫ごとにリンクフロー制御を実行できるように、異なる入口を提供します。ただし、これによりコード量が増加することは間違いないため、ソースを制御したい場合は、ソース制限を使用するのが最善です。
フロー制御にソースを使用したい場合は、Sentinel の RequestOriginParser を使用する必要があります。これは、ソースを解析するためのメソッド parseOrigin を提供します。ソースの解析方法はOriginやRefererなどに合わせて指定できますし、リクエストヘッダーのカスタマイズも可能です。
ここでは、カスタム リクエスト ヘッダーを使用してソースを指定します。リクエスト ヘッダーにはパラメーター ソースが含まれていると仮定します。

import com.alibaba.csp.sentinel.adapter.spring.webmvc.callback.RequestOriginParser;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
import java.util.Optional;


/**
 * @author pcc
 */
@Component
public class SentinelOriginRequestOriginParser implements RequestOriginParser {
    
    
    @Override
    public String parseOrigin(HttpServletRequest request) {
    
    
        String source = request.getHeader("source");
        /**
         * 当存在来源时我们直接设置来源为传入的值
         * 否则返回null
         */
        if (Optional.ofNullable(source).isPresent()) {
    
    
            return source;
        }
        return null;
    }
}

上記のコードでは、リクエスト ヘッダー内のソースをソースとして取得し、jemter を使用してリクエスト ヘッダー パラメーターのソースを設定する必要があります。ここでは 2 つの http リクエストに jemeter を使用し、1 つのリクエスト ヘッダー ソースは 1 つに設定され、 1 つのソースを 2 に設定します。以下はページ構成です:
ここに画像の説明を挿入します
上で設定したように、QPS が 100 より大きい場合、フロー制御は testFlowRule1 で実行され、この時点ではソース 2 を持つリクエストのみがフロー制御されます。たとえば、送信元が 2 つでない場合、QPS が 100 より大きくてもフロー制御は行われません。
ここに画像の説明を挿入します
上記はリクエストヘッダーにsource=twoを設定し、同時リクエスト数を160に設定した場合のリクエストです。予想通り、フロー制御が発生します。source=oneで同時実行数が160の場合、フローは発生しません。コントロール。

************************************************* * ********** 以下は API の紹介です********************************* *** **********************
API はコードを少し変更するだけでよく、他のページ構成を変更する必要はありません。

import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Collections;

/**
* @author pcc
*/
@Configuration
public class FlowConfig {
    
    

   @Bean
   public FlowRule getFlowRule() {
    
    
       FlowRule flowRule = new FlowRule();
       // 声明流控的资源
       flowRule.setResource("testChain");
       // 声明使用的流控规则:0 并发线程数,1 QPS
       flowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);

       // 流控规则设置-线程并发阈值2
       flowRule.setCount(100);
       // 来源没有默认值,必须手动设定,default表示对所有来源生效
       flowRule.setLimitApp("one");
       // 流控模式-链路
       flowRule.setStrategy(RuleConstant.STRATEGY_CHAIN);
       // 流控模式-链路-路径
       flowRule.setRefResource("/flow/testFlowRule1");


       // 将流控规则交给流控管理器
       FlowRuleManager.loadRules(Collections.singletonList(flowRule));
       return flowRule;
   }
}

8. クラスタ構成

クラスター モードを使用せずにクラスター サービスの場合、設定するルールは単一ノード用になります。
クラスター モードを使用します。クラスター サービスの場合、設定したルールはクラスター全体に適用でき、単一ノードのフロー制御を隠蔽ソリューションとして使用できます。これは実際にマイクロサービスがすべきモードです。使用する(クラスタの負荷がラウンドロビンの場合) ポーリングを使用する場合、クラスタモードとスタンドアロンモードの差は特に大きくありません。ポーリングを使用しない場合、その差は非常に大きくなります。
このモードについては別途説明する必要があり、ここであまりにも多くのことを書き込むと肥大化してしまいますので、今回はここでは紹介しません。
クラスター モードの正式な紹介: Sentinel フロー制御クラスター モード
ここに画像の説明を挿入します

6. 現在の制限認可ルール: AuthorityRule

認可ルールは実際にリソースのブラックリストとホワイトリストを設定します。リソースにホワイトリストが設定されている場合、未設定のソースはブラックリストに登録されます。逆も同様で、リソースにブラックリストが設定されている場合、未設定のソースはホワイトリストになります。

1.認可ルールページ/API

承認ルールを使用するための前提条件は、データ ソースを取得することです。これは、フロー制御のソースと同じです。RequestOriginParser を使用するだけです。ここでの RequestOriginParser とフロー制御の RequestOriginParser には違いはありません。設定が必要なページも非常にシンプルです。
注: 作者が認可を確認したところ、インターフェースへの認可は成功しましたが、通常のメソッドへの認可は適用されませんでした。実際、インターフェースが入ってきたことを考えると、メソッドへのアクセスを許可しないのはおかしいのですが、したがって、通常はインターフェースレベルでインターセプトされる必要があります。
ここに画像の説明を挿入します
これが設定されている場合、次のように、現在のインターフェイスにアクセスするときに、ソース 1 を持つリクエストのみが受信でき、その他は拒否されることを意味します。 ホワイトリストが複数ある場合はどうなりますか
ここに画像の説明を挿入します
? 次のように、構成中にカンマを使用して複数のホワイトリスト (またはブラックリスト) リソースを区切ることができます。
ここに画像の説明を挿入します
************************** ***** ******************************** 以下は API の紹介です************ * ************************************************
API としてはかなりページ構成の場合、構成はコードに移動されるだけで、他の変更は追加されません。新しいコードは次のとおりです。

  @Bean
  public AuthorityRule getAuthorityRule(){
    
    
      AuthorityRule rule = new AuthorityRule();
      // 授权规则管理的资源
      rule.setResource("/flow/testFlowRule1");
      // 授权策略:白名单0,黑名单1
      rule.setStrategy(RuleConstant.AUTHORITY_WHITE);
      //
      rule.setLimitApp("one,two");

      // 将授权规则交给授权管理器
      AuthorityRuleManager.loadRules(Collections.singletonList(rule));
      return rule;
  }

7. 電流制限ホットスポット ルール: ParamFlowRule

ホットスポット ルールは、リソース フロー制御に基づいてリソース リクエスト パラメーターのフローを制御するため、実際には、ホットスポット ルールをフロー制御ルールに含める必要があります。実際、ホットスポット ルールにより、フロー制御がより細かくなります。したがって、彼は実際にはフロー制御ルールに含まれる必要があります。さらに、ホットスポット ルールは QPS モードのホットスポットのみをサポートし、同時スレッドの数はサポートしません。興味深いことに、除外もサポートしています。
ホットスポット ルールの適用シナリオは主に、特定のデータへのアクセスが多すぎる場合や、サーバーに大きな負荷がかかる場合です。このデータのアクセス頻度を制御する必要があります。たとえば、比較的大規模なクエリ操作があり、type=10 はtype=10 はデータ量が多いのかもしれません。毎回このようなチェックをさせたくないので、type だけでフロー制御ができます。type=10 の場合はフロー制御が行われます。type=10 が等しい場合は、フロー制御が行われます。他の値にすると、フロー制御が不要になるか、通過できる QPS が大きくなります。

1. ホットスポット ルール ページ

これは、ホットスポット ルールの構成ページです。パラメータのタイプと名前を持つインターフェイスがあるとします。
ここに画像の説明を挿入します
上記のパラメータについて説明します。

  • パラメータ インデックス: インターフェイスのパラメータ リストの添え字。ここに入力すると、最初の添え字は 0 になります。
  • 単一マシンのしきい値: QPS しきい値
  • 統計ウィンドウ時間: ここでの QPS は、1 秒あたりのリクエスト数にデフォルト設定されていますが、統計の単位時間を変更することもできます。ここでは 10 秒に変更されています。これは、10 秒以内にタイプを運ぶリクエスト パラメータが 3 つある場合、フロー制御が行われることを意味します。トリガーされます。
  • クラスタ化するかどうか: ここでのクラスタ モードは、フロー制御のクラスタ モードと同じであり、違いはありません。
  • パラメータ例外: これは例外ルールを設定することと同じです。つまり、上記のフロー制御ルールは例外ルールに基づいて実行する必要があります。
  • パラメータのタイプ: ここでのパラメータ インデックスのタイプと一致している必要があります。タイプは文字列です。
  • 電流制限しきい値: パラメータ値の特定のしきい値。これにより、特定の値のしきい値を構成できます。たとえば、タイプが 10 で、同時実行性を 1 に制御したい場合、しきい値を次のように設定できます。それに対して1。他の値にはこの制限は適用されません。

これらのパラメータは理解しやすいため、センチネルに登録するためのインターフェイスを追加する必要があります。

@RequestMapping("/testParamFlowRule2")
@SentinelResource(
        value = "testParamFlowRule2",
        blockHandler = "testParamFlowRule2",
        blockHandlerClass = BlockMethod.class
)
public String testParamFlowRule2(@RequestParam("type") String type,@RequestParam("name") String name) throws Exception{
    
    
    log.info("{},{}",type,name);
    service.testChain();
    return "testFlowRule1 : success";
}

次に、次のようにリソースの blockhandler メソッドを指定する必要もあります。
注: これは静的である必要があり、BlockException が存在する必要があります。

/**
 * 热点流控
 * @param type
 * @param name
 * @return
 * @throws Exception
 */
public static String testParamFlowRule2(String type,String name,BlockException blockException) throws Exception{
    
    
    log.info("热点流控方法:{},{}",type,name);
    return "热点流控了 : success";
}

上記の構成によれば、表示されるべき効果は、タイプが 11 の場合は 10 秒ごとに最大 100 回アクセスできます (この手の速度ではクリックしにくい)、タイプが 10 の場合は、アクセスは10秒に1回まで、それ以外の場合は10秒に1回アクセス可能 3回訪問して酔った。

ここに画像の説明を挿入します
最初に type=11 を送信した場合は手動クリックしてもフロー制御されず、10 を送信すると 4 回目でフロー制御が行われることがわかります。

2. ホットスポット ルール - API

API 設定とページの違いは、設定項目がコード内に移動されることです。その他の違いはありません。ここではコードの記述のみが示されています。検証は上記と変わりません: 注: ほとんどの API 設定はサポートされていますこのページよりも機能が少し増えています
ので、興味があれば調べてみてくださいが、基本的には同じです。

    @Bean
    public ParamFlowRule getParamFlowRule(){
    
    
        ParamFlowRule paramFlowRule = new ParamFlowRule();
        // 热点流控-资源
        paramFlowRule.setResource("testParamFlowRule2");
        // 限流模式-必须QPS,默认就是QPS
        paramFlowRule.setGrade(RuleConstant.FLOW_GRADE_QPS);


        // 参数索引: 方法参数列表下标
        paramFlowRule.setParamIdx(0);
        // 单机阈值
        paramFlowRule.setCount(3);
        // 单机阈值的统计时间:默认1s,支持更改单位秒
        paramFlowRule.setDurationInSec(10);



        // 参数例外项
        ParamFlowItem paramFlowItem = new ParamFlowItem();
        // 参数例外项-参数类型:必须与setParamIdx对应的参数保持一致
        paramFlowItem.setClassType("java.lang.String");
        // 参数例外项-参数值
        paramFlowItem.setObject("10");
        // 参数例外项-限流阈值
        paramFlowItem.setCount(1);

        ParamFlowItem paramFlowItem2 = new ParamFlowItem();
        // 参数例外项-参数类型:必须与setParamIdx对应的参数保持一致
        paramFlowItem2.setClassType("java.lang.String");
        // 参数例外项-参数值
        paramFlowItem2.setObject("11");
        // 参数例外项-限流阈值
        paramFlowItem2.setCount(101);

        List<ParamFlowItem> list = new ArrayList<>();
        list.add(paramFlowItem);
        list.add(paramFlowItem2);
        paramFlowRule.setParamFlowItemList(list);

        // 加载热点流控规则
        ParamFlowRuleManager.loadRules(Collections.singletonList(paramFlowRule));
        return paramFlowRule;
    }

8. 電流制限システム ルール: SystemRule

先ほど紹介した各種ルールは単一リソースや単一インターフェースに対するものであり、システム全体の電流制限を保証するものではありませんが、システムルールjはシステム全体をより高いレベルで保護することを目的としています。 、単一リソースのフロー制御は隠蔽ソリューションとして使用でき、システム ルールは全体的なソリューションとして使用できます (クラスター モードに似ているものもありますが、同じではありません)。

1. システムルールページ/API

以下はシステム ルールの設定ページです。
ここに画像の説明を挿入します
まず、各パラメータの意味を見てみましょう。
システム ルールの公式ドキュメント: System Adaptive Current Limiting

  • LOAD: システムのload1は、適応型システム保護のヒューリスティック指標として使用されます。システム負荷 1 が設定されたしきい値を超え、システム内の現在の同時スレッド数が推定システム容量を超えると、システム保護がトリガーされます。
    注:
    1. システムの現在の同時スレッド数: maxQps * minRt は、これから大まかに計算できます。
    2. システム容量: 通常、CPU コア *2.5 に設定されます。
    3. Linux システムのみにload1 パラメーターがあり、稼働時間を表示するには、uptime を使用します。システム負荷
    ここに画像の説明を挿入します

  • RT: 単一マシン上のすべての入力トラフィックの平均 RT がしきい値に達すると、システム保護がトリガーされます (単位はミリ秒)。

  • スレッド数: 単一マシン上のすべての入力トラフィックの同時スレッド数がしきい値に達すると、システム保護がトリガーされます。

  • 入力 QPS: 単一マシン上のすべての入力トラフィックの QPS がしきい値に達すると、システム保護がトリガーされます。

  • CPU 使用率: システムの CPU 使用率がしきい値を超えると、比較的敏感なシステム保護がトリガーされます (値の範囲は 0.0 ~ 1.0)。

上記はシステム ルールでサポートされるすべてのパラメータであり、負荷や RT の設定など、異なる戦略を同時に設定するシステム ルールの設定をサポートします。システム ルールはシステム サーバー レベルでサーバーを保護します。上記のフロー制御、ホットスポット、承認、サーキット ブレーカーなどはすべてリソースまたはインターフェイスに基づいており、これが主な違いです。
設定された RT ルールは次のとおりです。
ここに画像の説明を挿入します
期待される結果: インターフェイスの平均 RT が 30 ミリ秒を超えると、フロー制御がトリガーされます。
以下は新しいインターフェースです。

    @RequestMapping("/testSystemRule")
    @SentinelResource(
            value = "testSystemRule",
            blockHandler = "testSystemRule",
            blockHandlerClass = BlockMethod.class
    )
    public String testSystemRule(@RequestParam("type") String type,@RequestParam("name") String name) throws Exception{
    
    
        log.info("{},{}",type,name);
        // 等待40ms,模仿RT超过30ms
        Thread.sleep(400);
        return "testSystemRule : success";
    }

以下は彼のフロー制御ブロックハンドラーメソッドです。

    /**
     * 系统规则
     */
    public static String testSystemRule(String type, String name,BlockException blockException) throws Exception{
    
    
        log.info("{},{}",type,name);
        return "系统规则-流控 : success";
    }

注:
1. システム ルールが設定値どおりに正確にトリガーされず、一部のパラメーターの感度が高くないことが確認されています。感度が高くないことを確認するために、ここでは RT が使用されます。 current limit は
、アクセスされたインターフェイスまたはリソースに対応する電流制限メソッドを呼び出しませんが、統一された電流制限メソッド: BlockExceptionHandler を実装するだけです。詳細については、この記事の 4 番目のセクションのセクション 4.2 の導入部分を参照してください
ここに画像の説明を挿入します
。ブロックハンドラーを設定しても、システムの電流制限方法は依然として統一された電流制限方法を使用します。この時点ではリクエストはインターフェースに入っておらず、システムレベルで傍受されているため、当然のことながらシステムレベルでの電流制限方式が採用されるはずです。
************************************************* * ********** 以下は API の紹介です********************************* *************************

   /**
    * 系统限流
    */
   @Bean
   public SystemRule getSystemRule() {
    
    
       SystemRule systemRule = new SystemRule();

       // 平均RT:2ms
       systemRule.setAvgRt(2);

       // 加载规则
       SystemRuleManager.loadRules(Collections.singletonList(systemRule));
       return systemRule;
   }

他の設定と検証、およびページとの間に違いはないため、ここでは繰り返しません。

9. まとめ

実際、この記事にはまだ書かれていない部分がいくつかあります。クラスタリング、フロー制御のための Sentinel とゲートウェイの統合、運用環境のデプロイ中の Sentinel コードの変更などです。ただ、この記事もすでに50,000ポイントに達しており、これ以上書くと長くなって足巻きになってしまうので、センチネルに関するその他の情報はまた別の記事で更新したいと思います。
Sentinel の主な機能は、ダウングレード、サーキット ブレーカー、フロー制御、承認などを実行することです。フロー制御は、実際には通常のフロー制御、ホットスポット データ フロー制御、システム フロー制御などに分類できます。最も重要なことは、通常のフロー制御が最も一般的に作成されるアプリケーションであるということです。通常のフロー制御は 2 つの戦略をサポートします: QPS と同時スレッド数 (TPS と見なすこともできますが、TPS ではありません) 各戦略は、ダイレクト、アソシエーション、リンクの 3 つの異なるフロー制御モードをサポートします。QPS シナリオでは、各フロー制御モードは、失敗、予熱、キューイングなどのさまざまなフロー制御効果の編集もサポートしています。実際、Sentinel は難しくありませんが、まだ多くの知識があります。この記事は、詳細情報として使用できます。公式ドキュメントよりも詳細なガイドですので、このドキュメントの使い方を学び、近くを通る学生の皆様のお役に立てれば幸いです。

おすすめ

転載: blog.csdn.net/m0_46897923/article/details/132796974