「SpringCloudAlibabaマイクロサービスアーキテクチャ」トピック(15)-Spring Cloud AlibabaSentinel @ SentinelResourceアノテーション構成の詳細

1はじめに

前の章では@SentinelResourceアノテーションを使用しましたが、この記事では、@ SentinelResourceアノテーションを使用して制御リソースを柔軟に定義する方法と、制御戦略を構成する方法について説明します。リソースポイントを定義した後、Dashboard現在の制限およびダウングレード戦略を設定することにより、リソースポイントを保護できます。同時に、@SentinelResource電流制限と劣化が発生した場合の例外処理戦略を指定することもできます。次に、電流制限とダウングレードがどのように達成されるかを見てみましょう。

2. @SentinelResourceのケース分析

以下では、2つの状況での@SentinelResourceアノテーションの使用を紹介します。

按资源名称进行限流;
按URL请求路径进行限流;

2.1。リソース名による現在の制限

したがって、モジュール[springcloudalibaba-sentinel-service8401]を変換する必要があります。

[A]新しいRateLimitController.javaを作成します

@SentinelResource主にリソースを定義するために使用されます。blockHandlerは、ダウングレードメソッドを指定するために使用されます。

package com.bruce.controller;

import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.bruce.pojo.JsonResult;
import com.bruce.pojo.Payment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;


@RestController
public class RateLimitController {
    
    

    /**
     * 根据资源名称进行限流
     */
    @GetMapping("/limitByResource")
    @SentinelResource(value = "limitByResource", blockHandler = "blockHandlerLimitByResource")
    public JsonResult limitByResource() {
    
    
        return new JsonResult(200, "根据资源名称进行限流", new Payment(20200906L, UUID.randomUUID().toString()));
    }

    /**
     * 服务兜底降级方法
     */
    public JsonResult blockHandlerLimitByResource(BlockException exception) {
    
    
        return new JsonResult(500, exception.getClass().getCanonicalName() + "\t 服务不可用");
    }

    /**
     * 根据URL进行限流
     */
    @GetMapping("/limitByUrl")
    @SentinelResource(value = "limitByUrl")
    public JsonResult limitByUrl() {
    
    
        return new JsonResult(200, "根据URL进行限流", new Payment(20200906L, UUID.randomUUID().toString()));
    }

}

[B]フロー制御ルールを構成します。詳細については下の図を参照してください
ここに画像の説明を挿入します
ここに画像の説明を挿入します

[C]リソース名テストによる現在の制限

通常のブラウザアクセス:http:// localhost:8401 / limitByResource
ここに画像の説明を挿入します
上記は通常のアクセスです。つまり、1秒間に1つのリクエストのみが送信されます。以下では、このインターフェイスに対して1秒間にクレイジーなリクエストを行います。http:// localhost: 8401 / limitByResource
ここに画像の説明を挿入します
we 1秒間のリクエスト数が1を超えると、インターフェースが制限され、マイクロサービスが利用できなくなることがわかりました。これらは前の章で紹介されています。友達はなじみがないと思います。次に、追加の問題を見てみましょう。8401サービスを停止し、Sentinelコンソールに戻ります。
ここに画像の説明を挿入します
マイクロサービスの後で停止すると、 、以前に構成されたフロー制御ルールはすべて消えました。明らかに、Sentinelのフロー制御ルールは一時的なものであり、現在は永続的ではありません。ここでは最初に問題を紹介し、後で解決方法について説明します。

2.2.URLによるフローの制限

[A] URLテストによる制限フロー
ここに画像の説明を挿入します
通常のブラウザアクセス:http:// localhost:8401 / limitByUrl、1
ここに画像の説明を挿入します
秒に1回、1秒に1回は通常のアクセスです。つまり、1秒以内に1つのリクエストのみが送信されます。このインターフェースは数秒以内に:http:// localhost:8401 / limitByUrl
ここに画像の説明を挿入します
/ limitByUrlメソッドがblockHandlerダウングレードメソッドを指定しなかったため、現在の制限の迅速な信頼性もデフォルトのエラーレポートであることがわかりました[Sentinelによってブロックされました(フロー制限)]、上の図に示すように。

収益を処理する上記の方法の現在の問題を要約します。

1.系统默认的,没有体现我们自己的业务要求;
2.依照现有条件,我们自定义的处理方法又和业务代码耦合在一块,不直观;
3.每个业务方法都需要添加一个降级方法,代码膨胀加剧;
4.没有体现全局统一的处理方法;

3.顧客定義の電流制限処理ロジック

デフォルトでは、Sentinelの現在の制御リソースの制限処理は、直接例外をスローします。これは、合理的なビジネス事業やフロントエンドドッキングがない場合に実行できますが、通常の状況では、ユーザービジネスを改善するために、フローが制限された後に特別な処理が実装されます。厳密なエラーは表示したくありません。これには、電流制限処理ロジックをカスタマイズする必要があります。

[A]カスタム電流制限処理ロジック用のCustomBlockHandlerクラスを作成します

package com.bruce.controller;

import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.bruce.pojo.JsonResult;

/**
 * @Description 自定义BlockHandler限流处理类
 * 说明: 必须是static静态方法
 */
public class CustomBlockHandler {
    
    

    public static JsonResult customBlockHandlerMethodA(BlockException exception) {
    
    
        return new JsonResult(500, "[客户自定义限流处理逻辑]--->customBlockHandlerMethodA");
    }

    public static JsonResult customBlockHandlerMethodB(BlockException exception) {
    
    
        return new JsonResult(500, "[客户自定义限流处理逻辑]--->customBlockHandlerMethodB");
    }
}

【B】RateLimitController.java

  blockHandlerClass: 指定限流逻辑处理类;
  blockHandler: 指定限流处理方法, 对应blockHandlerClass处理类中的方法名称;
 /**
   * 客户自定义限流处理逻辑
   * blockHandlerClass: 指定限流逻辑处理类
   * blockHandler: 指定限流处理方法, 对应blockHandlerClass处理类中的方法名称
   */
  @GetMapping("/customBlockHandler")
  @SentinelResource(value = "customBlockHandler",
          blockHandlerClass = CustomBlockHandler.class,
          blockHandler = "customBlockHandlerMethodA")
  public JsonResult customerBlockHandler() {
    
    
      return new JsonResult(200, "客户自定义限流处理逻辑", new Payment(20200906L, UUID.randomUUID().toString()));
  }

主に2つのことをしました:

通过@SentinelResource注解的blockHandler属性制定具体的处理函数
实现处理函数,该函数的传参必须与资源点的传参一样,并且最后加上BlockException异常参数;同时,返回类型也必须一样。

Hystrixに精通している読者は、この設計がHystrixCommandで定義されたフォールバックに非常に類似しており、理解しやすいことに気付くはずです。

[C]センチネル構成
ここに画像の説明を挿入します
[d]テスト

通常のブラウザアクセス:http:// localhost:8401 / customBlockHandler 1
ここに画像の説明を挿入します
秒に1回、1秒に1回、どちらも通常のアクセスです。つまり、1秒間に1つのリクエストのみが送信されます。このインターフェースを、1秒間にクレイジーにリクエストしましょう:http: // localhost:8401 / customBlockHandler
ここに画像の説明を挿入します
customBlockHandlerMethodA指定したダウングレードメソッドがであるため、トラフィックがしきい値を超えると、ダウングレード処理もcustomBlockHandlerMethodAメソッドのロジックであることがわかります上記の方法により、すべてのダウングレード処理が抽出されます。これは、ビジネスロジック間の分離に役立ちます。これをお勧めします。

4.より多くの注釈属性の説明

ビューのSentinelソースコードを、あなたが見ることができるSentinelResourceの定義valueentryTyperesourceTypeblockHandlerfallbackdefaultFallback次のようにその他の財産、ソースコードを:

/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.alibaba.csp.sentinel.annotation;

import com.alibaba.csp.sentinel.EntryType;

import java.lang.annotation.*;

/**
 * The annotation indicates a definition of Sentinel resource.
 *
 * @author Eric Zhao
 * @since 0.1.1
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface SentinelResource {
    
    

    /**
     * @return name of the Sentinel resource
     */
    String value() default "";

    /**
     * @return the entry type (inbound or outbound), outbound by default
     */
    EntryType entryType() default EntryType.OUT;

    /**
     * @return the classification (type) of the resource
     * @since 1.7.0
     */
    int resourceType() default 0;

    /**
     * @return name of the block exception function, empty by default
     */
    String blockHandler() default "";

    /**
     * The {@code blockHandler} is located in the same class with the original method by default.
     * However, if some methods share the same signature and intend to set the same block handler,
     * then users can set the class where the block handler exists. Note that the block handler method
     * must be static.
     *
     * @return the class where the block handler exists, should not provide more than one classes
     */
    Class<?>[] blockHandlerClass() default {
    
    };

    /**
     * @return name of the fallback function, empty by default
     */
    String fallback() default "";

    /**
     * The {@code defaultFallback} is used as the default universal fallback method.
     * It should not accept any parameters, and the return type should be compatible
     * with the original method.
     *
     * @return name of the default fallback method, empty by default
     * @since 1.6.0
     */
    String defaultFallback() default "";

    /**
     * The {@code fallback} is located in the same class with the original method by default.
     * However, if some methods share the same signature and intend to set the same fallback,
     * then users can set the class where the fallback function exists. Note that the shared fallback method
     * must be static.
     *
     * @return the class where the fallback method is located (only single class)
     * @since 1.6.0
     */
    Class<?>[] fallbackClass() default {
    
    };

    /**
     * @return the list of exception classes to trace, {@link Throwable} by default
     * @since 1.5.1
     */
    Class<? extends Throwable>[] exceptionsToTrace() default {
    
    Throwable.class};
    
    /**
     * Indicates the exceptions to be ignored. Note that {@code exceptionsToTrace} should
     * not appear with {@code exceptionsToIgnore} at the same time, or {@code exceptionsToIgnore}
     * will be of higher precedence.
     *
     * @return the list of exception classes to ignore, empty by default
     * @since 1.6.0
     */
    Class<? extends Throwable>[] exceptionsToIgnore() default {
    
    };
}

以下に、これらの属性の役割について説明します。

  • value:必須項目であるリソース名。対応するルールはリソース名から見つける必要があるため、これを構成する必要があります。
  • entryType:エントリタイプ、オプション、INとOUTの2つのオプションがあり、デフォルトはEntryType.OUTです。
public enum EntryType {
    
    
    IN("IN"),
    OUT("OUT");
}
  • blockHandler:BlockHandlerは、BlockExceptionを処理する関数の名前に対応します(オプション)。blockHandler関数のアクセススコープはパブリックである必要があり、戻り値の型は元のメソッドと一致する必要があり、パラメーターの型は元のメソッドと一致する必要があり、最後に追加のパラメーターが追加されます。型はBlockExceptionです。
  • blockHandlerClass:デフォルトでは、blockHandler関数は元のメソッドと同じクラスにある必要があります。他のクラスの関数を使用する場合は、対応するクラスのClassオブジェクトとしてblockHandlerClassを指定する必要があります。対応する関数は次のようにする必要があります。静的関数。それ以外の場合は解析できません。
  • fallback:フォールバック関数名(オプション)。例外がスローされたときにフォールバック処理ロジックを提供するために使用されます。フォールバック関数は、すべてのタイプの例外を処理できます(exceptionsToIgnoreで除外された例外タイプを除く)。
  • fallbackClass:fallbackClassのアプリケーションはblockHandlerClassに似ています。フォールバック関数は、デフォルトで元のメソッドと同じクラスにある必要があります。他のクラスの関数を使用する場合は、対応するクラスのClassオブジェクトとしてfallbackClassを指定できます。対応する関数は静的関数である必要があり、そうでない場合は解析できません。
  • defaultFallback(1.6.0以降):defaultFallbackメソッドが構成されていない場合、デフォルトでここに表示されます。デフォルトのフォールバック関数名(オプション)。通常、一般的なフォールバックロジックに使用されます。デフォルトのフォールバック関数は、すべてのタイプの例外を処理できます(exceptionsToIgnoreで除外された例外タイプを除く)。フォールバックとdefaultFallbackの両方が構成されている場合、フォールバックのみが有効になります。
  • exceptionsToIgnore(1.6.0以降):どの例外を除外し、例外統計に含めず、フォールバックロジックに入らないかを指定するために使用されますが、そのままスローされます。

注:1.6.0より前のバージョンのフォールバック機能は、DegradeExceptionのみを処理し、ビジネス例外を処理することはできません。

5.まとめ

この記事では主に、@SentinelResourceアノテーションを使用して制御リソースを柔軟に定義する方法と、特定のメソッドの呼び出し電流制限または外部リソースの呼び出し電流制限を制御するための制御戦略を構成する方法を要約します。

おすすめ

転載: blog.csdn.net/BruceLiu_code/article/details/113934265