春の雲アリババ|センチネル:交通国防高等戦闘兵分散システム

春の雲アリババ|センチネル:交通国防高等戦闘兵分散システム

この記事を読む前に、それは読むことをお勧めします「春クラウドアリババを|センチネル:トラフィック分散システムの防御戦闘兵の基礎」

1.センチネル統合装うとRestTemplate

Sentinelは今装うとRestTemplateの両方をサポートし、私たちはふりを使用した場合、設定ファイルにセンチネル装うのサポートを開く必要があり、対応する依存性を導入する必要があります。feign.sentinel.enabled=true同じ時間に参加する必要がありますopenfeign starterに依存しているsentinel starter自動化されたコンフィギュレーションクラス効果。RestTemplateを使用している場合、あなたは、Beanのの建設RestTemplateで追加する必要があり@SentinelRestTemplate、コメントRestTemplateためセンティネルのサポートを開きます。

1.1親プロジェクトのセンチネル・springcloud高の作成:

親プロジェクトのpom.xml次のように:

リスト:アリババ/センチネル-springcloudハイ/のpom.xml
***

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

公共Sentinelは、ナコス行うサービスセンターの導入を制御する流れないコンポーネントに導入されました。

1.2サブプロジェクトprovider_serverを作成します。

次のようにapplication.ymlプロフィール:

リスト:アリババ/センチネル-springcloudハイ/ provider_server /のpom.xml
***

server:
  port: 8000
spring:
  application:
    name: spring-cloud-provider-server
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.44.129:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8720
management:
  endpoints:
    web:
      cors:
        allowed-methods: '*'

インターフェイスのテストクラスHelloController.javaは次のとおりです。

代码清单:アリババ/センチネル-springcloud高/ provider_server / srcに/メイン/ javaの/ COM / springcloud / provider_server /コントローラ/ HelloController.java
***

@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello(HttpServletRequest request) {
        return "Hello, port is: " + request.getLocalPort();
    }
}

1.3サブプロジェクトconsumer_serverを作成します。

次のようにサブプロジェクトがのpom.xmlを依存しています:

リスト:アリババ/センチネル-springcloudハイ/ consumer_server /のpom.xml
***

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

次のようにapplication.ymlプロフィール:

代码清单:アリババ/センチネル-springcloud高/ consumer_server / srcに/メイン/リソース/ application.yml
***

server:
  port: 9000
spring:
  application:
    name: spring-cloud-consumer-server
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.44.129:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8719
management:
  endpoints:
    web:
      cors:
        allowed-methods: '*'
feign:
  sentinel:
    enabled: true

ここでの使用feign.sentinel.enabled=trueセンティネルの装うためのオープンをサポート。

インターフェーステストクラスHelloController.java

代码清单:アリババ/センチネル-springcloud高/ consumer_server / srcに/メイン/ javaの/ COM / springcloud / consumer_server /コントローラ/ HelloController.java
***

@RestController
public class HelloController {
    @Autowired
    HelloRemote helloRemote;

    @Autowired
    RestTemplate restTemplate;

    @GetMapping("/helloByFeign")
    public String helloByFeign() {
        return helloRemote.hello();
    }

    @GetMapping("/helloByRestTemplate")
    public String helloByRestTemplate() {
        return restTemplate.getForObject("http://spring-cloud-provider-server/hello/", String.class);
    }
}

Sentinelは、我々は、追加のコメントせずに装う場所を使用して、統合のために行っています。同時に、@FeignClientすべてのプロパティのノートは、Sentinelは両立させています。

Ch122ConsumerServerApplication.javaは、以下のメインクラスを起動します。

代码清单:アリババ/センチネル-springcloud高/ consumer_server / srcに/メイン/ javaの/ COM / springcloud / consumer_server / ConsumerServerApplication.java
***

@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class Ch122ConsumerServerApplication {

    public static void main(String[] args) {
        SpringApplication.run(Ch122ConsumerServerApplication.class, args);
    }

    @Bean
    @LoadBalanced
    @SentinelRestTemplate
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}

RestTemplateを使用する場合に増加する必要が@SentinelRestTemplateオープンセンチネルのRestTemplateをサポートすること。

1.4テスト

エンジニアリングprovider_serverとconsumer_serverを起動し、provider_serverスタートアップコンフィギュレーションを変更し、2つのインスタンスを起動し、アクセスするブラウザを開きます。http:// localhost:9000 / helloByFeign て、http:// localhostを:9000 / helloByRestTemplate 、 数回更新し、あなたが交互にページを見ることができますディスプレイHello, port is: 8000Hello, port is: 8001、正常なバランス電流負荷を示す、今センチネルコンソールは、図示のように表示します。

1.5フローコントロールテスト

ストリームのこの時点で左クラスタ制御を選択示すように、フロー制御をクリックします。

ここでは、図に示すように、[追加]をクリックし、単純なルール、1の構成されたQPSの上限を設定します。

ここでQPS、QPSは、それは我々がここでHTTPを試験した場合、高速リフレッシュを繰り返す必要があり、単に秒あたりの訪問数が何であるかを説明すること:// localhostを:9000 / helloByFeignて、http:// localhostを:9000 / helloByRestTemplate 、 さわやかの過程で私たちは、ページのようなエラーメッセージが表示されますことを見ることができます。Blocked by Sentinel (flow limiting)私たちは成功を制限センチネルを設定する必要があること、そして、あなたは成功したの数を見ることができる、のは、センチネルコンソールを見てみましょう、我々は同じように、アクセスを制限しています図:

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

要約では、我々は装うとRestTemplateはセンチネルを統合利用を導入し、センチネルコンソールにQPS電流制限を行い、成功を制限し、電流制限の成功の後、デフォルトでは、リソースを制限するセンチネルプロセスが制御され、直接投げます。よりよいサービス利用者への順で合理的なビジネスの事業やドッキング例前端のそうかもしれないが、通常の状況では、制限された後、いくつかの特別な処理を実現します、我々は鈍いエラーを表示したくありません。このセクションでは、我々はサービス低下の過程を紹介します。

2.1サブプロジェクトconsumer_fallbackを作成

次のようにサービス低下のクラスHelloRemoteFallBack.javaを装います:

代码清单:アリババ/センチネル-springcloud高/ consumer_fallback / srcに/メイン/ javaの/ COM / springcloud / consumer_fallback /フォールバック/ HelloRemoteFallBack.java
***

@Component
public class HelloRemoteFallBack implements HelloRemote {
    @Override
    public String hello() {
        return "Feign FallBack Msg";
    }
}

次のように対応して、HelloRemote.javaの一部に行われる必要があることは、サービス低下のクラスの私たちのサービス低下の実装をトリガは、そのような電流制限ことが構成されました:

代码清单:ch12_2 / ch12_2_consumer_fallback / srcに/メイン/ javaの/ COM / springcloud /書籍/ ch12_2_consumer_fallback /リモート/ HelloRemote.java
***

@FeignClient(name = "spring-cloud-provider-server", fallback = HelloRemoteFallBack.class)
public interface HelloRemote {
    @GetMapping("/hello")
    String hello();
}

fallback = HelloRemoteFallBack.class指定されたサービス分解処理クラスHelloRemoteFallBack.class

RestTemplateサービス劣化ツールExceptionUtil.java次のように:

代码清单:アリババ/センチネル-springcloud高/ consumer_fallback / srcに/メイン/ javaの/ COM / springcloud / consumer_fallback /リモート/ HelloRemote.java
***

public class ExceptionUtil {

    private final static Logger logger = LoggerFactory.getLogger(ExceptionUtil.class);

    public static SentinelClientHttpResponse handleException(HttpRequest request, byte[] body, ClientHttpRequestExecution execution, BlockException ex) {
        logger.error(ex.getMessage(), ex);
        return new SentinelClientHttpResponse("RestTemplate FallBack Msg");
    }
}

ここでは、あまりにも、私たちはそれを書いた後、Ch122ConsumerFallbackApplication.javaコードは以下のとおりであるRestTemplateトリガーハンドラクラスのサービス低下のコードの実行を作り、Beanの場所として登録RestTemplateを変更する必要があります。

代码清单:アリババ/センチネル-springcloud高/ consumer_fallback / srcに/メイン/ javaの/ COM / springcloud / consumer_fallback / ConsumerFallbackApplication.java
***

@Bean
@LoadBalanced
@SentinelRestTemplate(blockHandler = "handleException", blockHandlerClass = ExceptionUtil.class)
public RestTemplate restTemplate() {
    return new RestTemplate();
}

これは、注意すべきで@SentinelRestTemplate注釈プロパティは、(制限をサポートしblockHandlerblockHandlerClass)および(ダウングレードfallbackfallbackClass)処理を。

前記blockHandlerまたはfallback属性に対応し、対応する方法でなければならないblockHandlerClassか、fallbackClass静的メソッドを属性。

@SentinelRestTemplateノート(制限blockHandlerblockHandlerClass)およびダウングレード(fallbackfallbackClass)プロパティを記入することは必須ではありません。

センチネルが融合さRestTemplate呼び出しを使用する場合、戻りRestTemplate request block by sentinel方式情報を、またはプロセスによって調製されてもよい自体に情報対応を返します。ここで提供してSentinelClientHttpResponseリターン情報を構築するため。

2.2テスト

シーケンシャルスタートprovider_serverとconsumer_fallback二つのサブプロジェクト。最初のHTTPへの代替ブラウザ:// localhostを:9090 / helloByFeignて、http:// localhostを:9090 / helloByRestTemplate、その後、センチネルコンソールを開き、2つのインターフェイス上の電流制限情報を増やし、あなたはここに制限することに注意してください情報は、図示のように、特に、リソースのストリームに追加されました:

ブラウザでリフレッシュ二つのリンク、2つの制限情報は、ブラウザで正しく表示することができ、テストが成功し、示したように、我々は、トラフィック統計情報-拒否を見ることができ、再びセンチネルコンソールを参照してください。

制限3.センチネル統合サービス・ゲートウェイ

Sentinelは、現在主流の春クラウドゲートウェイ、Zuul、ゲートウェイは限定的であることなどのAPIをサポートしています。示すように、公式のチャートを見てください:

このの公式見解から、我々はZuulのセンチネルが達成3つのフィルターを通して主に制限し、見ることができ、春クラウドゲートウェイの通過であるSentinleGatewayFilterBlockRequestHandler完了します。

センチネル1.6.0導入センチネルAPI Gatewayアダプタの共通モジュールは、このモジュールは、ゲートウェイAPIおよびカスタムエンティティと管理ロジックを制限するルールが含まれています。

  • GatewayFlowRule:API Gatewayのシーンのためにルールを制限するゲートウェイが制限ルールが異なるルートまたはカスタムをグループ化するAPIのために制限することができ、カスタマイズすることはリクエストパラメータの制限カスタマイズ現在サポートしている、などのヘッダー、送信元IP、 。
  • ApiDefinition:APIは、URLにマッチのいくつかの組み合わせとして見ることができる、ユーザ定義のパケットを定義します。たとえば、私たちは**下記のグループ化my_api APIに戻す/ my_api、要求されたパスモード/ fooの/ **および/バズと呼ばれるAPIを定義することができます。電流制限は、このAPIのカスタムグループ化ディメンションに制限することができるとき。

3.1 Zuul 1.1

Sentinelは、Zuul 1.xのアダプタモジュールを提供Zuulゲートウェイの電流制限と資源寸法を提供することができます。

  • 寸法経路:すなわち、ルーティングエントリSpring構成ファイル内に配置され、リソース名は(プロキシフィールドRequestContextのに対応する)ルートIDに対応します
  • カスタムAPIの寸法:ユーザーはいくつかのパケットを定義するためにAPIから提供されたセンチネルAPIを使用することができます

3.1.1は、サブプロジェクトを作成しますzuul_server

次のようにプロジェクトがのpom.xmlを依存しています:

リスト:アリババ/センチネル-springcloudハイ/ zuul_server /のpom.xml
***

<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-zuul</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-zuul-adapter</artifactId>
</dependency>

ここにいるのでsentinel-zuul-adapter、に含まれていないspring-cloud-starter-alibaba-sentinel別の手作業を導入する必要が。

3.1.2プロフィールapplication.yml次のように:

リスト:アリババ/センチネル-springcloudハイ/ zuul_server / srcに/メイン/リソース/ application.yml
***

server:
  port: 18080
spring:
  application:
    name: spring-cloud-zuul-server
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.44.129:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8720
zuul:
  routes:
    consumer-route:
      path: /consumer/**
      serviceId: spring-cloud-consumer-fallback

3.1.3ダウングレード定義されたクラスZuulFallbackProvider.javaは次のとおりです。

代码清单:アリババ/センチネル-springcloud高/ zuul_server / srcに/メイン/ javaの/ COM / springcloud / zuul_server /フォールバック/ ZuulFallbackProvider.java
***

public class ZuulFallbackProvider implements ZuulBlockFallbackProvider {
    @Override
    public String getRoute() {
        return "*";
    }

    @Override
    public BlockResponse fallbackResponse(String route, Throwable cause) {
        RecordLog.info(String.format("[Sentinel DefaultBlockFallbackProvider] Run fallback route: %s", route));
        if (cause instanceof BlockException) {
            return new BlockResponse(429, "Sentinel block exception", route);
        } else {
            return new BlockResponse(500, "System Error", route);
        }
    }
}

次のように3.1.4は同時に、我々はセンチネルフィルターの春、コンフィギュレーション・クラスの3注入する必要があります。

代码清单:アリババ/センチネル-springcloud高/ zuul_server / srcに/メイン/ javaの/ COM / springcloud / zuul_server /設定/ ZuulConfig.java
***

@Configuration
public class ZuulConfig {
    @Bean
    public ZuulFilter sentinelZuulPreFilter() {
        // We can also provider the filter order in the constructor.
        return new SentinelZuulPreFilter();
    }

    @Bean
    public ZuulFilter sentinelZuulPostFilter() {
        return new SentinelZuulPostFilter();
    }

    @Bean
    public ZuulFilter sentinelZuulErrorFilter() {
        return new SentinelZuulErrorFilter();
    }

    /**
     * 注册 ZuulFallbackProvider
     */
    @PostConstruct
    public void doInit() {
        ZuulBlockFallbackManager.registerProvider(new ZuulFallbackProvider());
    }

}

最終的に、あなたは増加を開始する前に、JVMの起動パラメータを設定する必要が-Dcsp.sentinel.app.type=1APIゲートウェイタイプのセンチネルConsoleサービスを開始し、私たちに伝えるために、。

3.1.5テスト

シーケンシャルエンジニアリングプロモーターprovider_server、consumer_fallback、zuul_server、アクセスにブラウザを開きます。http:// localhost:18080 /消費者/ helloByFeign、我々はとしてzuul_serverのサービスを見るためにセンチネルコンソールを開きます。

我々はまだQPS 1で、ポリシーを制限カスタマイズ、我々は再び設定します。http:// localhostを:18080 /消費者/ helloByFeignページ、そして、ページが既に発生する正の電流制限、および表示の内容を制限した後、次のとおりです。

{"code":429, "message":"Sentinel block exception", "route":"consumer-route"}

リソース制限の定義は、示されているような定義を制限し、間違った場所を定義しないことをここで注意してください:

3.2春クラウドゲートウェイ

バージョン1.6.0の当初から、センチネルは春クラウドゲートウェイアダプタモジュールを提供しています、2つのリソースは、電流制限寸法を提供することができます。

  • 寸法経路:すなわち、ルーティングエントリSpring構成ファイル内に配置され、ルートIDという名前の、対応するリソース
  • カスタムAPIの寸法:ユーザーはいくつかのパケットを定義するためにAPIから提供されたセンチネルAPIを使用することができます

3.2.1サブプロジェクトgateway_serverを作成

次のようにプロジェクトがのpom.xmlを依存しています:

リスト:アリババ/センチネル-springcloudハイ/ gateway_server /のpom.xml
***

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
<dependency>
    <groupId>com.alibaba.csp</groupId>
    <artifactId>sentinel-spring-cloud-gateway-adapter</artifactId>
</dependency>

3.2.2プロフィールapplication.yml次のように:

リスト:アリババ/センチネル-springcloudハイ/ gateway_server / srcに/メイン/リソース/ application.yml
***

server:
  port: 28080
spring:
  application:
    name: spring-cloud-gateway-server
  cloud:
    nacos:
      discovery:
        server-addr: 192.168.44.129:8848
    sentinel:
      transport:
        dashboard: localhost:8080
        port: 8720
    gateway:
      enabled: true
      discovery:
        locator:
          lower-case-service-id: true
      routes:
        - id: consumer_server
          uri: lb://spring-cloud-consumer-fallback
          predicates:
            - Method=GET

3.2.3グローバルGatewayConfig.java次のカテゴリ:

以前、我々はまた、春の約2センチネル春クラウドゲートウェイフィルタの注入が必要になりますサブセクション、とZuul:SentinelGatewayFilterSentinelGatewayBlockExceptionHandler、ここで多くの場所で、センチネルV1.6.0のバージョンで春クラウドゲートウェイのサポートを追加したことは異常で、完璧ではないので、治療がSentinelGatewayBlockExceptionHandler唯一の作者自身が再実装例外メッセージではなく、良い私たちのシステムの組み合わせと下流、返すことができSentinelGatewayBlockExceptionHandler、そして名前をJsonSentinelGatewayBlockExceptionHandlerリターン・パラメータはJSONになるように定義されている、これはもはやであるセンチネルはありません注入しSentinelGatewayBlockExceptionHandlerたが、代わりに、私は実装を所有しますJsonSentinelGatewayBlockExceptionHandler

代码清单:アリババ/センチネル-springcloud高/ gateway_server / srcに/メイン/ javaの/ COM / springcloud / gateway_server /設定/ GatewayConfig.java
***

@Configuration
public class GatewayConfig {
    private final List<ViewResolver> viewResolvers;
    private final ServerCodecConfigurer serverCodecConfigurer;

    public GatewayConfig(ObjectProvider<List<ViewResolver>> viewResolversProvider, ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolversProvider.getIfAvailable(Collections::emptyList);
        this.serverCodecConfigurer = serverCodecConfigurer;
    }

    @Bean
    @Order(Ordered.HIGHEST_PRECEDENCE)
    public JsonSentinelGatewayBlockExceptionHandler jsonSentinelGatewayBlockExceptionHandler() {
        // Register the block exception handler for Spring Cloud Gateway.
        return new JsonSentinelGatewayBlockExceptionHandler(viewResolvers, serverCodecConfigurer);
    }

    @Bean
    @Order(-1)
    public GlobalFilter sentinelGatewayFilter() {
        return new SentinelGatewayFilter();
    }
}

3.2.4クラスJsonSentinelGatewayBlockExceptionHandler.javaのダウングレードは、次のとおりです。

代码清单:アリババ/センチネル-springcloud高/ gateway_server / srcに/メイン/ javaの/ COM / springcloud / gateway_server /例外/ JsonSentinelGatewayBlockExceptionHandler.java
***

public class JsonSentinelGatewayBlockExceptionHandler implements WebExceptionHandler {
    private List<ViewResolver> viewResolvers;
    private List<HttpMessageWriter<?>> messageWriters;

    public JsonSentinelGatewayBlockExceptionHandler(List<ViewResolver> viewResolvers, ServerCodecConfigurer serverCodecConfigurer) {
        this.viewResolvers = viewResolvers;
        this.messageWriters = serverCodecConfigurer.getWriters();
    }

    private Mono<Void> writeResponse(ServerResponse response, ServerWebExchange exchange) {
        ServerHttpResponse serverHttpResponse = exchange.getResponse();
        serverHttpResponse.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        byte[] datas = "{\"code\":403,\"msg\":\"Sentinel block exception\"}".getBytes(StandardCharsets.UTF_8);
        DataBuffer buffer = serverHttpResponse.bufferFactory().wrap(datas);
        return serverHttpResponse.writeWith(Mono.just(buffer));
    }

    @Override
    public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
        if (exchange.getResponse().isCommitted()) {
            return Mono.error(ex);
        }
        // This exception handler only handles rejection by Sentinel.
        if (!BlockException.isBlockException(ex)) {
            return Mono.error(ex);
        }
        return handleBlockedRequest(exchange, ex)
                .flatMap(response -> writeResponse(response, exchange));
    }

    private Mono<ServerResponse> handleBlockedRequest(ServerWebExchange exchange, Throwable throwable) {
        return GatewayCallbackManager.getBlockHandler().handleRequest(exchange, throwable);
    }

    private final Supplier<ServerResponse.Context> contextSupplier = () -> new ServerResponse.Context() {
        @Override
        public List<HttpMessageWriter<?>> messageWriters() {
            return JsonSentinelGatewayBlockExceptionHandler.this.messageWriters;
        }

        @Override
        public List<ViewResolver> viewResolvers() {
            return JsonSentinelGatewayBlockExceptionHandler.this.viewResolvers;
        }
    };
}

私はちょうど書き換えるwriteResponse()方法で情報を返しますが、読者が自分のニーズに応じて変更することができる必要がある、簡単な変更は、JSON形式になっています話します。

3.2.5テスト

順次provider_server、consumer_serverとgateway_server、配置gateway_serverのJVMの起動パラメータを出発-Dcsp.sentinel.app.type=1示すように、。

お使いのブラウザを開き、訪問ます。http:// localhost:28080 / helloByFeign、 数回更新し、ページに戻り、正常にHello, port is: 8000、オープンセンチネルコンソール、トラフィック制限ポリシーを設定、QPSの上限が1である場合、ブラウザのページを更新し、そして、我々が見ることができますブラウザ情報への復帰を制限します:

{"code":403,"msg":"Sentinel block exception"}

テストは成功です。

おすすめ

転載: www.cnblogs.com/babycomeon/p/11516011.html