Spring Cloud のゲートウェイ コンポーネントの紹介

ゲートウェイの理解

ゲートウェイは または に似て海关ます大门出入都需要经过这个网关他の人は、この門をくぐらないと中身が見えません。これはゲートウェイで行うことができます条件过滤。たとえば、対応するキーのみがゲートに入ることができます。ゲートウェイは、ゲートと同様に、常に外部にさらされています

ゲートウェイなし

  • フロントエンドは、各サービスの IP とポートを記憶する必要があります

  • サービスのデプロイが複数ある場合、フロント エンドはサービスを独自に割り当てる必要があります。

ゲートウェイを使用

  • フロントエンドは各サービスの IP とポートを覚えておく必要はありません。要求をゲートウェイに送信するだけでよく、ゲートウェイはリソース パスに従ってそれを行います。路由跳转

  • 安全控制ゲートウェイは、トークンの検証、電流制限などを実行できます。

  • できる负载均衡

ゲートウェイの理解

Zuul を置き換えるために Spring 公式 Web サイトによって開始された一連のゲートウェイ コンポーネントです。

それはできるように設計されています路由跳转更加方便、灵活が、強力なものを提供します过滤器功能例: IP ブラックリスト、トークン検証など。

webFlux フレームワークに基づいて、webFlux フレームワークの最下層は、高性能 Reactor モード通信フレームワークである Netty を使用します。


Gateway は、Spring 5、Spring Boot 2、Project Reactor などのテクノロジーに基づいて、Spring エコシステムの上に構築された API ゲートウェイ サービスです。

ゲートウェイは、API をルーティングするためのシンプルで効果的な方法を提供し、回路遮断、電流制限、再試行などの強力なフィルター機能を提供することを目的としています。

① ゲートウェイの動作原理

クライアントがリクエストを Gateway に送信すると、Gateway HandlerMapping がマッピングを比較して一致するルートを見つけ、それを Gateway WebHandler に送信します。Handler は、指定されたフィルターを介して実際のビジネス ロジックにリクエストを分配し、それを返します。

フィルターにコードを追加できます。

  • 请求之前[pre]バリデーションなどを行う

  • 请求之后[post]ログ出力などを行う

ゲートウェイのコア ロジック: リソース パスに従ってルーティングと転送を行い、フィルター チェーンを実行します。

②Gatewayの3つのコアコンセプト

ルート

eureka と組み合わせて動的ルーティングを行う

コンポーネント:ルーティング ID、一意のリソース ロケーター URI、一連のアサーション、一連のフィルター

ルート述語が true の場合、URL は構成されたルートと一致します

断言(Predicate)

ブール式を返します

フィルター

ゲートウェイのフィルターは、ゲートウェイ フィルター(ルート用) とグローバル フィルター(グローバル)に分けられます。

フィルターにバリデーションルールとレスポンス処理を記述可能

③ゲートウェイとNginxの違い

Nginx は、現在の制限、負荷分散、およびルーティングのために nginx.conf 構成ファイルを変更する必要があります

Gateway と eureka の組み合わせにより自動ルーティング ジャンプを実現し、Ribbon Collection によりロード バランシングを実現します。ゲートウェイは、構成を通じて電流制限を実装することもできます

 

 

ルーティングの使用

①アクセスの流れ

②ロイングサービス

@RestController
public class LoginController {

    @GetMapping("doLogin")
    public String doLogin(String username,String password){
        System.out.println(username+" -> "+password);
        String token = UUID.randomUUID().toString();
        return token;
    }
}

②ゲートウェイサーバー

ゲートウェイの依存関係

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

ルーティングを構成する

server:
  port: 80
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      routes: # 路由组
        - id: login-service-route # 路由ID 保证唯一
          uri: http://localhost:8080 # uri唯一资源定位符 url唯一资源标识符
          predicates: # 断言
            - Path=/doLogin # 和服务中的路径匹配

④プログラマティックルーティング

ルーティングと転送は、構成ファイルの助けを借りずにエンコードによって実現されます

@Configuration
public class RouteConfig {

    @Bean
    public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
        return builder.routes()
                .route("anime-id", r->r.path("/anime").uri("https://www.bilibili.com"))
                .route("variety-id",r->r.path("/variety").uri("https://www.bilibili.com"))
                .build();
    }
}

uri背後のリソース パスがpathルート インと同じである場合、ゲートウェイはpathルート インをuri背後にスプライスしません。

プログラムと構成ファイルを組み合わせることができます

動的ルーティング

ルーティングと転送中に URL が直接ハードコーディングされ、IP とポートもハードコーディングされると、ゲートウェイは負荷分散の効果を達成できなくなります。サービス名のみを提供し、この名前を使用して対応するサービスを見つけ、負荷分散の効果を達成する必要があります

ゲートウェイ サービスも登録センターに登録すると、ゲートウェイはすべてのサービス情報を取得できるようになります。

ゲートウェイは、登録センターのサービスのリストに従って、転送ごとに服务名为路径動的ルートを作成します

①第一の実施方法

Gateway の負荷分散機能を有効にするには、lb (Load Balance)プロトコルを使用します。

server:
  port: 80
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      routes: # 路由组
        - id: login-service-route # 路由ID 保证唯一
          # uri: http://localhost:8080 # uri唯一资源定位符 url唯一资源标识符
          uri: lb://login-service # lb://服务名
          predicates:
            - Path=/doLogin # 和服务中的路径匹配

 呼び出し: http://localhost/doLogin

②第二の実施方法

サービス検出を使用して動的ルートを自動的に作成し、負荷分散を実現します

server:
  port: 80
spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      discovery:
        locator:
           enabled: true # 开启动态路由
           lower-case-service-id: true # 将注册列表中的服务名小写

断言

プロジェクトが開始されると、Gateway は次のようないくつかのルーティング アサーション ファクトリをロードします。

assertion は route に some を追加することです匹配规则. 送信されたリクエストがこれらを満たす場合は规则アクセスできます. そうでない場合は 404. 簡単に言えば、これらの一致ルールはブール式であり、入力する場合は true、拒否する場合は false です。

①分類

 

②使う

構成ファイルで、ルートを操作します。動的ルーティングはアサーションを使用できません

spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      routes:
        - id: login-service-route
          uri: lb://login-service
          predicates:
            - Path=/doLogin
            - Method=GET,POST # GET,POST请求能够访问
            - After=2022-11-02T17:23:16.423+08:00[Asia/Shanghai] # 在指定时间后才能访问 通过ZonedDateTime获取
            - Query=username,admin. # 必须给username传值 后面的值必须是:adminx

フィルター

ゲートウェイのフィルターはサーブレットのフィルターに似ており、ユーザーは着信 HTTP 要求と HTTP 応答を変更します。

GatewayFilter (特定のルート用) と GlobalFilter (グローバル フィルタリング) に分割されます。

①カスタムグローバルフィルター

トークン検証や電流制限などのカスタム フィルターにビジネス ロジックを記述します。

@Component
public class TestFilter implements GlobalFilter {

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 获取请求对象
        ServerHttpRequest request = exchange.getRequest();
        RequestPath path = request.getPath();
        // 打印路由以及服务名
        System.out.println(path);
        HttpHeaders headers = request.getHeaders();
        // 获取主机IP
        String ip = headers.getHost().getHostName();
        System.out.println(ip);
        // 获取响应对象
        ServerHttpResponse response = exchange.getResponse();
        // 放过
        return chain.filter(exchange);
    }
}

 フィルターの順序を定義する

@Component
public class TestFilter implements Ordered {

    @Override
    public int getOrder() {
        // 数字越小 越往前
        return 0;
    }
}

戻り値処理

// 获取响应对象
ServerHttpResponse response = exchange.getResponse();
// 设置响应头
response.getHeaders().set("content-Type","application/json;charset=UTF-8");
// 封装返回数据
Map<String,Object> map = new HashMap<>();
map.put("code", 401);
map.put("msg","没有该权限");
ObjectMapper objectMapper = new ObjectMapper();
try {
    // 将map集合转为byte数组
    byte[] bytes = objectMapper.writeValueAsBytes(map);
    // 将byte数组包装成一个数据缓冲包
    DataBuffer wrap = response.bufferFactory().wrap(bytes);
    // 返回
    return response.writeWith(Mono.just(wrap));
} catch (JsonProcessingException e) {
    e.printStackTrace();
}

制限する

一定期間内に、ユーザーのアクセス頻度を制限します。

①電流制限モデル

ファンネル アルゴリズム、トークン パス アルゴリズム、電卓アルゴリズム、ウィンドウ スライディング アルゴリズム

目的を達成する: トークンは、使用できるほど速く生成することはできません

  1. システムは、事前に構成されたレートでトークンを生成します。

  2. トークン バケットのしきい値を設定します。バケットがいっぱいになると、余分なトークンは直接破棄されます

  3. クライアントはリクエストを送信するときにトークンを取得する必要があります

  4. トークンを取得しないと、リクエストに正常にアクセスできません

  5. トークンを取得したらサービスにアクセスし、業務処理完了後にトークンを削除します

  6. バケット内のトークンの数が最小量に達すると、使用されたトークンが返されます

② ゲートウェイでの電流制限

Gateway には RequestRateLimiterGatewayFilterFactory が組み込まれており、トークン バケット アルゴリズムとして Redis と組み合わされています。Redis の依存関係をインポートする必要があります

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
</dependency>

 トラフィック制限ルールを構成する

@Configuration
public class RequestLimiterConfig {

    /*
      基于IP做限流
     */
    @Bean
    @Primary // 主候选
    public KeyResolver ipKeyResolver(){
        return exchange-> Mono.just(exchange.getRequest().getHeaders().getHost().getHostName());
    }

    /*
      基于API接口最限流
     */
    @Bean
    public KeyResolver apiKeyResolver(){
        return exchange -> Mono.just(exchange.getRequest().getPath().toString());
    }
}

構成ファイルを変更する

spring:
  application:
    name: gateway-server
  cloud:
    gateway:
      enabled: true # 默认开启Gateway
      routes:
        - id: login-service-route
          uri: lb://login-service
          predicates:
            - Path=/doLogin
          filters:
            - name: RequestRateLimiter # 过滤器名称
              args:
                key-resolver: '#{@ipKeyResolver}' # Bean对象的名字
                redis-rate-limiter.replenishRate: 1 # 每秒钟生产多少令牌
                redis-rate-limiter.burstCapacity: 3 # 令牌桶中的容量

特定のルートのみ

クロスドメイン構成

クロスドメイン:CORS同一オリジン ポリシー。

ゲートウェイはサービスのエッジであるため、すべての要求はゲートウェイを通過する必要があり、クロスドメイン構成はゲートウェイに書き込まれます。

プログラマティック

@Configuration
public class CorsConfig {
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.addAllowedMethod("*");
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(new PathPatternParser());
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }
}

構成ファイル

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]': # 针对那些路径
            allowCredentials: true # 可以携带Cookie
            allowedHeaders: '*'
            allowedMethods: '*'
            allowedOrigins: '*'

面接の質問

マイクロサービス ゲートウェイとは

Spring Cloud Gateway は、Spring 5.x、Spring Boot 2.0、Project Reactor などのテクノロジに基づいて Spring が開発したゲートウェイで、マイクロサービス アーキテクチャ向けのシンプルで効果的な統合 API ルーティング管理方法を提供することを目的としています。Spring Cloud エコシステムのゲートウェイとして、 Spring Cloud Gateway は Netflix Zuulを置き換えることを目指しています . 統一されたルーティング方法を提供するだけでなく、セキュリティ、監視/インジケーター、およびフィルターチェーンに基づくゲートウェイの基本機能も提供します。弾性。

 

ゲートウェイを使用する利点

Spring Cloud Gateway は、Zuul 1.x のアップグレード バージョンおよび置き換えと見なすことができます. Netty を使用して、Zuul 2 よりも早く非同期 IO を実装することで、Zuul 1.x よりもシンプルで効率的で、Spring Cloud に近いものを実現します. API ゲートウェイ。
Spring Cloud Gateway は、Router と Filter を明確に区別します。優れた機能は、多くの組み込みのすぐに使える機能があり、SpringBoot 構成または手動のコーディング チェーン呼び出しを通じてそれらすべてを使用できることです
たとえば、10 個の組み込みルーターがあるため、それらを直接構成し、ヘッダー、パス、ホスト、またはクエリに従ってルーティングを行うことができます。
たとえば、一般的なフィルターとグローバルなフィルターを区別し、20 種類のフィルターと 9 種類のグローバルなフィルターを内蔵し、それらすべてを直接使用することができます。もちろんカスタムフィルターもとても便利です。

zuulと spring cloud ゲートウェイの比較

  • zuul: Netflix に属し、サーブレットに基づいて実装されています. ブロッキング API であり、長い接続をサポートしていません.
  • ゲートウェイ: springcloud 自身が開発したマイクロサービス ゲートウェイで、Spring5 をベースに構築されており、レスポンシブなノンブロッキング API を実装し、長い接続をサポートできます。

ゲートウェイの構成

  • ルーティング: ゲートウェイの基本モジュールで、ID、ターゲット URI、一連のアサーション、および一連のフィルターで構成されます
  • アサーション: ツアーにアクセスするためのアクセス ルールであり、ヘッダーやパラメーターなど、http 要求からの任意のコンテンツを照合するために使用できます。
  • フィルター: これは私たちが通常フィルターと呼んでいるものです. 一部のリクエストをフィルタリングするために使用されます. ゲートウェイには独自のデフォルトフィルターがあります. 詳細については, 公式ウェブサイトを参照してください. フィルターをカスタマイズすることもできますが, 2つの実装が必要です.インターフェイス、順序付きおよびグローバル フィルタ

おすすめ

転載: blog.csdn.net/weixin_45934981/article/details/130151588