SpringCloud-GateWay 新世代ルーティングゲートウェイ

マイクロサービス ゲートウェイについての理解、マイクロサービス ゲートウェイにどちらを選択するか、GateWay を使用する理由、GateWay が zuul よりも優れている理由を教えてください。

ゲートウェイ: Spring Cloud API ゲートウェイ コンポーネント (非常に詳細)

nginx ゲートウェイとゲートウェイ ゲートウェイの違い

SpringCloud Gateway 公式サイト

SpringCloud Gateway 公式サイトの中国語版

概要

Spring Cloud Gateway とは

Cloud ファミリー バケットの非常に重要なコンポーネントはゲートウェイであり、1.x バージョンでは Zuul ゲートウェイとして使用されていましたが、
2.x バージョンでは、zuul のアップグレードによりチケットがスキップされ続け、SpringCloud はついにゲートウェイを開発しました。 replace Zuul. 、
つまり SpringCloud Gateway の文です: gateway is a replacement for the original zuul1.x version
ここに画像の説明を挿入

簡単な説明

Gateway は、Spring 5、Spring Boot 2、Project Reactor などのテクノロジーに基づいて、Spring エコシステムの上に構築された API ゲートウェイ サービスです。ゲートウェイは、API をルーティングするためのシンプルで効果的な方法を提供し、ヒューズ、電流制限、再試行など
のいくつかの強力なフィルター機能を提供することを目的としています。

SpringCloud Gateway は Spring Cloud の新しいプロジェクトで、Spring 5.0+Spring Boot 2.0 と Project Reactor およびその他のテクノロジに基づいており、マイクロサービス アーキテクチャにシンプルで効果的な統合 API ルーティング管理方法を提供することを目的としています。

Spring Cloud エコシステムのゲートウェイとして、SpringCloud Gateway は Zuul を置き換えることを目指しています.Spring Cloud 2.0 以降では、Zuul 2.0 以降の最新の高性能バージョンを統合せず、Zuul 1.x 非 Reactor モードを引き続き使用しますの古いバージョン。ゲートウェイのパフォーマンスを向上させるために、Spring Cloud Gateway は WebFlux フレームワークに基づいて実装され、WebFlux フレームワークの最下層には高性能な Reactor モード通信フレームワーク Netty が使用されます。

Spring Cloud Gateway の目標は、統一されたルーティング方法を提供し、フィルター チェーンに基づいてゲートウェイの基本機能 (セキュリティ、監視/インジケーター、電流制限など)を提供することです。

概要: SpringCloud Gateway で使用される Webflux の Reactor-Netty レスポンシブ プログラミング コンポーネントは、下部にある Netty 通信フレームワークを使用します。

Gateway は webflux と reactor-netty を統合します。これらはどちらもノンブロッキング レスポンシブ プログラミングのための高性能フレームワークです。
ここに画像の説明を挿入

マイクロサービス ゲートウェイのアーキテクチャ上の場所

その中で、ロードバランシングはNginxであり、ゲートウェイクラスターはすべてのマイクロサービスの入り口です。

ここに画像の説明を挿入

Zuul では、なぜゲートウェイが再び出てきたのですか?

1. Neflixは信頼性が低く、zuul2.0はチケットをスキップしており、長い間リリースされていません

一方で、Zuul 1.0 はメンテナンス段階に入っており、ゲートウェイは SpringCloud チームによって開発されているため、親善製品であり、信頼できます。
そして多くの機能はZuulを使わず、とてもシンプルで便利です。

Gateway は、非同期およびノンブロッキング モデルに基づいて開発されているため、パフォーマンスについて心配する必要はありません。Netflix はずっと前に最新の Zuul 2.x をリリースしましたが、
Spring Cloud には統合計画がないようです。また、Netflix関連のコンポーネントはメンテナンス期間に入ったと発表されていますが、今後はどうなりますか?

多くの側面を考慮すると、Gateway は理想的なゲートウェイの選択肢です。

2. Spring Cloud Gateway は、
Spring Framework 5、Project Reactor、Spring Boot 2.0 をベースに構築されており、
動的ルーティング: 任意のリクエスト属性に一致することができ、
ルーティングに Predicate (アサーション) と Filter (フィルター) を指定できます。 、
Hystrixサーキットブレーカ機能統合、
Spring Cloudサービスディスカバリ機能統合、
Predicate(アサーション)とFilter(フィルタ)の書きやすさ、
リクエスト電流制限機能、
パス書き換え対応。
3. SpringCloud Gateway と Zuul の違い
SpringCloud Finchley の公式バージョン以前は、Spring Cloud が推奨するゲートウェイは Netflix が提供する Zuul でした。

1. Zuul 1.x はブロック I/O に基づく API ゲートウェイです。

2. Zuul 1.x は Servlet 2.5 に基づいており、ブロッキング アーキテクチャを使用しています. 長い接続 (WebSocket など) をサポートしていません. Zuul の設計パターンは Nginx に似ています. ワーカー スレッドが完了するまでスレッドはブロックされます.ただし、違いは、Nginx は C++ で実装され、Zuul は Java で実装され、JVM 自体のロードが初めて遅くなり、Zuul のパフォーマンスが比較的低下することです。

3. Zuul 2.x の概念はより高度であり、Netty のノンブロッキングに基づいて長い接続をサポートすることを望んでいますが、SpringCloud はまだ統合されていません。Zuul 2.x のパフォーマンスは、Zuul 1.x に比べて大幅に改善されています。パフォーマンスに関しては、公式のベンチマーク テストによると、Spring Cloud Gateway の RPS (1 秒あたりのリクエスト数) は Zuul の 1.6 倍です。

4. Spring Cloud Gateway は、ノンブロッキング API を使用して、Spring Framework 5、Project Reactor、および Spring Boot 2 に基づいて構築されています。

5. Spring Cloud Gateway は WebSocket もサポートしており、Spring と緊密に統合されているため、開発エクスペリエンスが向上しています。

Zuul1.x モデル

Springcloud に統合された Zuul バージョンは、Tomcat コンテナーを使用し、従来のサーブレット IO 処理モデルを使用します。

サーブレットのライフサイクルとは、シリコンバレーwebの中間講座を受講された方ならご存知のことでしょうか? サーブレットは、サーブレットコンテナのライフサイクルによって管理されています。
コンテナーが起動すると、サーブレット オブジェクトを構築し、初期化のためにサーブレット init() を呼び出します。
コンテナーが実行されると、要求を受け入れ、要求ごとにスレッドを割り当て (通常はスレッド プールからアイドル スレッドを取得します)、次に service( )。
コンテナーが閉じられたら、サーブレット destroy() を呼び出してサーブレットを破棄します。

上記のモデルの短所:
サーブレットは単純なネットワーク IO モデルです. 要求がサーブレット コンテナーに入ると、サーブレット コンテナーはそれに対してスレッドをバインドします. このモデルは、同時実行性が高くないシナリオに適用できます. しかし、同時実行性が高くなると (jemeter を使用して風を押すなど)、スレッドの数が増加し、スレッド リソースのコストが高くなり (オンラインでのテキストの切り替え、大量のメモリ消費)、リクエストの処理時間に深刻な影響を与えます。いくつかの単純なビジネス シナリオでは、要求ごとにスレッドを割り当てることは望ましくなく、1 つまたは少数のスレッドのみが非常に同時の要求を処理できます。このビジネス シナリオでは、サーブレット モデルには利点がありません。

つまり、Zuul 1.X はサーブレットに基づくブロッキング処理モデルです。つまり、Spring は、すべてのリクエストを処理し、サーブレットのブロッキング処理によって処理されるサーブレット (DispatcherServlet) を実装します。だからSpringcloud Zuulはサーブレットモデルの欠点を取り除けない

ゲートウェイモデル

struts2、springmvc などの従来の Web フレームワークはすべて、サーブレット API とサーブレット コンテナーに基づいて実行されます。
しかし、 Servlet3.1 以降では、非同期ノンブロッキング サポート (webflux と reactor-netty)
がありますWebFlux は典型的なノンブロッキング非同期フレームワークであり、そのコアは Reactor の関連 API に基づいて実装されています。従来の Web フレームワークと比較して、Netty、Undertow、Servlet3.1 などのコンテナーで実行できます。ノンブロッキング + 関数型プログラミング (Spring5 では java8 を使用できる必要があります)

Spring WebFlux は、Spring 5.0 で導入された新しいレスポンシブ フレームワークです.Spring MVC とは異なり、Servlet API に依存する必要はありません.完全に非同期でノンブロッキングであり、Reactor ベースのレスポンシブ フロー仕様を実装しています.

3つのコアコンセプト

ルート

ルーティングは、ゲートウェイを構築するための基本的なモジュールです. ID, ターゲット URI, 一連のアサーションとフィルタで構成されます. アサーションが true の場合, ルートが一致します.

Predicate(断言)

参照は Java8 の java.util.function.Predicate です。
開発者は、HTTP 要求のすべて (要求ヘッダーや要求パラメーターなど) を照合し、要求がアサーションに一致する場合にルーティングできます。

フィルター

Spring フレームワークの GatewayFilter のインスタンスを参照します. フィルターを使用すると、リクエストがルーティングされる前または後に変更できます.

要約する

ここに画像の説明を挿入

Web 要求は、いくつかの一致条件を介して実際のサービス ノードに配置されます。そして、この転送プロセスの前後で、細かい制御が行われます。
述語は一致条件であり、
フィルターは全能のインターセプターとして理解できます。これらの 2 つの要素とターゲット uri を使用して、特定のルートを実現できます。

ゲートウェイ ワークフロー

コア ロジック: ルート転送 + 実行フィルター チェーン
ここに画像の説明を挿入
クライアントは Spring Cloud Gateway にリクエストを送信します。次に、ゲートウェイ ハンドラー マッピングで要求に一致するルートを見つけ、それをゲートウェイ Web ハンドラーに送信します。

次に、ハンドラーは要求を実際のサービスに送信して、指定されたフィルター チェーンを介してビジネス ロジックを実行し、戻ります。
フィルターは、プロキシ要求が送信される前 (「前」) または後 (「後」) にビジネス ロジックを実行する可能性があるため、点線で区切られています。

「pre」タイプのフィルターでは、パラメーター検証、権限検証、フロー監視、ログ出力、プロトコル変換などを行うことができ、
「post」タイプのフィルターでは、応答内容、応答ヘッダー、ログ出力、トラフィック監視を変更できます。など、非常に重要な役割を果たしています。

はじめに 構成

依存関係を追加する

    <dependencies>
        <!--gateway-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
        <!--eureka-client-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- 引入自己定义的api通用包,可以使用Payment支付Entity -->
        <dependency>
            <groupId>com.atguigu.springcloud</groupId>
            <artifactId>cloud-api-commons</artifactId>
            <version>${project.version}</version>
        </dependency>
        <!--一般基础配置类-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <scope>runtime</scope>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

構成ファイル

GateWay もサービスであり、eureka サービス管理センターにも登録する必要があります。

server:
  port: 9527

spring:
  application:
    name: cloud-gateway
  cloud:
    gateway:
      routes:
        - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001          #匹配后提供服务的路由地址(要转发的ip)
          predicates:
            - Path=/payment/get/**         # 断言,路径相匹配的进行路由(接口地址)

        - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
          uri: http://localhost:8001          #匹配后提供服务的路由地址(要转发的ip)
          predicates:
            - Path=/payment/lb/**         # 断言,路径相匹配的进行路由(接口地址)

eureka:
  instance:
    hostname: cloud-gateway-service
  client: #服务提供者provider注册进eureka服务列表内
    service-url:
      register-with-eureka: true
      fetch-registry: true
      defaultZone: http://eureka7001.com:7001/eureka

Gateway サービスモジュールにspring☁️gateway: routes:設定を追加し、転送するサービスを設定
ゲートウェイ追加前のアクセス:http://localhost:8001/payment/get/31
ゲートウェイ追加後のアクセス:http:// localhost: 9527/payment/get/31 は 8001 のインターフェースにもアクセスできます
ここに画像の説明を挿入

ゲートウェイ ルーティングを構成するには、次の 2 つの方法があります。

1. 上記のように yml で構成します (通常は yml 構成を使用します)
2. RouteLocator Bean をコードに挿入します
例: たった今、9527 ゲートウェイを介して外部ネットワーク上の Baidu News Web サイトにアクセスします
構成ファイルを追加します: GateWayConfig

説明:
path_route_atguigu は自分で付けた名前です
アクセス: http://localhost:9527guonei は http://news.baidu.com/guonei に転送されます

package com.atguigu.springcloud.config;

import org.springframework.cloud.gateway.route.RouteLocator;
import org.springframework.cloud.gateway.route.builder.RouteLocatorBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @auther zzyy
 * @create 2020-02-21 11:42
 */
@Configuration
public class GateWayConfig
{
    
    
    /**
     * 配置了一个id为route-name的路由规则,
     * 当访问地址 http://localhost:9527/guonei时会自动转发到地址:http://news.baidu.com/guonei
     * @param builder
     * @return
     */
    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder)
    {
    
    
        RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();

        routes.route("path_route_atguigu",
                r -> r.path("/guonei")
                        .uri("http://news.baidu.com/guonei")).build();
        return routes.build();
    }
}

マイクロサービス名による動的ルーティングの実現

デフォルトでは、Gateway はレジストリによって登録されたサービス リストに基づいて動的ルートを作成し、レジストリ
上のマイクロサービス名を使用して転送用の動的ルートを作成し、動的ルーティングの機能を実現します。

application.yml 構成ファイルを変更し
、検出構成を追加して、レジストリ
uri: lb:// サービス プロバイダーのサービス名からルートを動的に作成する機能を有効にします。
ここに画像の説明を挿入

server:
 port: 9527

spring:
 application:
   name: cloud-gateway
 cloud:
   gateway:
     discovery:
       locator:
         enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
     routes:
       - id: payment_routh #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
         # uri: http://localhost:8001          #匹配后提供服务的路由地址
         uri: lb://cloud-payment-service #匹配后提供服务的路由地址(服务提供方的服务名称)
         predicates:
           - Path=/payment/get/**         # 断言,路径相匹配的进行路由

       - id: payment_routh2 #payment_route    #路由的ID,没有固定规则但要求唯一,建议配合服务名
         # uri: http://localhost:8001          #匹配后提供服务的路由地址
         uri: lb://cloud-payment-service #匹配后提供服务的路由地址
         predicates:
           - Path=/payment/lb/**         # 断言,路径相匹配的进行路由

eureka:
 instance:
   hostname: cloud-gateway-service
 client: #服务提供者provider注册进eureka服务列表内
   service-url:
     register-with-eureka: true
     fetch-registry: true
     defaultZone: http://eureka7001.com:7001/eureka

述語(アサーション)の使用

ここに画像の説明を挿入

Spring Cloud Gateway は、Spring WebFlux HandlerMapping インフラストラクチャの一部としてルート マッチングを使用します。
Spring Cloud Gateway には、多数の組み込み Route Predicate ファクトリが含まれています。これらの述語はすべて、HTTP 要求のさまざまな属性に一致します。複数の Route Predicate ファクトリを組み合わせることができます

Spring Cloud Gateway が Route オブジェクトを作成するとき、RoutePredicateFactory を使用して Predicate オブジェクトを作成し、Predicate オブジェクトを Route に割り当てることができます。Spring Cloud Gateway には、多数の組み込みルート述語ファクトリーが含まれています。

これらの述語はすべて、HTTP 要求のさまざまな属性に一致します。さまざまな述語ファクトリを組み合わせて、論理 AND を渡すことができます。

人間的に言えば、yml でいくつかのフィルター構成を追加できます。リクエストが来たら、構成条件を満たしていれば転送できます。フィルター条件を満たしていなければ、アクセスは許可されません。

一定時間後に有効

たとえば、特定の時間後に特定のサービスの転送が有効になる必要があり、この時間より前に長時間アクセスが許可されない場合は、
(- After=2020-02-21T15:51:37.485+08: 00[Asia/Shanghai])
ここに画像の説明を挿入
は、次の時間形式に注意する必要があります。このように記述する必要があります。次のコードでこの時間形式を取得できます。

        ZonedDateTime zbj = ZonedDateTime.now(); // 默认时区
        System.out.println(zbj);
        // 亚洲上海
        // 2022-06-03T18:48:23.118+08:00[Asia/Shanghai]
Cookie アクセスを制限する

ここに画像の説明を挿入

curl コマンドを使用して、cmd でリクエスト アクセスをシミュレートできます。

curl http://localhost:9588/paymentInfo --cookie "username=zzyy"

ここに画像の説明を挿入

制限リクエスト ヘッダー

ここに画像の説明を挿入
ここに画像の説明を挿入

制限リクエスト方法

ここに画像の説明を挿入
ここに画像の説明を挿入

Filter フィルターの使用

ルート フィルターを使用して、着信 HTTP 要求と返された HTTP 応答を変更できます。ルート フィルターは、指定されたルートに対してのみ使用できます。

Spring Cloud Gateway にはさまざまな組み込みルーティング フィルターがあり、それらはすべて GatewayFilter のファクトリ クラスによって生成されます。

ライフサイクル

  1. ビジネスロジックの前に
  2. ポストビジネスロジック

タイプ

  1. GatewayFilter 単一
  2. GlobalFilter グローバル

https://cloud.spring.io/spring-cloud-static/spring-cloud-gateway/2.2.1.RELEASE/reference/html/#the-addrequestparameter-gatewayfilter-factory

カスタム フィルター

カスタムフィルターは何に使用できますか?

  1. グローバル ロギング
  2. 統合ゲートウェイ認証

2 つの主要なインターフェイス: GlobalFilter、Ordered を実装します。

package com.atguigu.springcloud.filter;

import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.util.Date;

/**
 * @auther zzyy
 * @create 2020-02-06 18:21
 */
@Component //必须加,必须加,必须加
public class MyLogGateWayFilter implements GlobalFilter,Ordered
{
    
    
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain)
    {
    
    
        System.out.println("time:"+new Date()+"\t 执行了自定义的全局过滤器: "+"MyLogGateWayFilter"+"hello");

        String uname = exchange.getRequest().getQueryParams().getFirst("uname");
        if (uname == null) {
    
    
            System.out.println("****用户名为null,无法登录");
            exchange.getResponse().setStatusCode(HttpStatus.NOT_ACCEPTABLE);
            return exchange.getResponse().setComplete();
        }
        return chain.filter(exchange);
    }

    @Override
    public int getOrder()
    {
    
    
        return 0;
    }
}

おすすめ

転載: blog.csdn.net/qq_44154912/article/details/125113696