新しいSpring Cloud Gatewayを探る

新しいSpring Cloud Gatewayの探索

1. 概要

この記事では、Spring 5、Spring Boot 2、Project Reactorに基づく新しいAPIであるSpring Cloud Gatewayプロジェクトの主な機能について説明します。

このツールは、単一のファサードの背後に複数のサービスを隠す方法として、マイクロサービスアプリケーションでよく使用される、すぐに使用可能なルーティングメカニズムを提供します。

Spring Cloud Gatewayプロジェクトを使用しないゲートウェイパターンの説明については、previous articleを確認してください。

2. ルーティングハンドラー

リクエストのルーティングに重点を置いて、Spring Cloud GatewayはリクエストをGateway Handler Mappingに転送します。これにより、特定のルートに一致するリクエストで何を行うべきかが決まります。

ゲートウェイハンドラーがRouteLocator:を使用してルート構成を解決する方法の簡単な例から始めましょう

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
      .route("r1", r -> r.host("**.example.com")
        .and()
        .path("/example")
        .uri("http://example.com"))
      .route(r -> r.host("**.example.com")
        .and()
        .path("/myOtherRouting")
        .filters(f -> f.prefixPath("/myPrefix"))
        .uri("http://othersite.com")
        .id("myOtherID"))
    .build();
}

このAPIの主要な構成要素をどのように利用したかに注目してください。

  • Route –はゲートウェイのプライマリAPIです。 これは、特定のID(ID)、宛先(URI)、および一連の述語とフィルターによって定義されます

  • Predicate –はJava 8のPredicate –であり、ヘッダー、メソッド、またはパラメーターを使用してHTTPリクエストを照合するために使用されます

  • Filter –は標準のSpringのWebFilterです

3. 動的ルーティング

Zuulと同様に、Spring CloudGatewayはリクエストをさまざまなサービスにルーティングする手段を提供します。

ルーティング構成は、純粋なJava(セクション2.1の例に示されているRouteLocator)を使用するか、プロパティ構成を使用して作成できます。

spring:
  application:
    name: gateway-service
  cloud:
    gateway:
      routes:
      - id: example
        uri: example.com
      - id: myOtherRouting
        uri: localhost:9999

4. ルーティングファクトリ

Spring Cloud Gatewayは、Spring WebFluxHandlerMappingインフラストラクチャを使用してルートを照合します。

また、多くの組み込みルート述語ファクトリが含まれています。 これらの述部はすべて、HTTP要求のさまざまな属性と一致します。 複数のルート述語ファクトリは、論理的な「および」を介して組み合わせることができます。

ルートマッチングは、プログラムによって、または異なるタイプのルート述語ファクトリを使用した構成プロパティファイルを介して適用できます。

4.1. Before Route Predicate Factory

Beforeルート述語ファクトリは1つのパラメーターを取ります:datetime.この述語は、現在のdatetimeの前に発生する要求に一致します。

spring:
  cloud:
    gateway:
      routes:
      - id: before_route
        uri: http://example.com
        predicates:
        - Before=2017-09-11T17:42:47.789-07:00[America/Alaska]

Java構成は次のように表すことができます。

//..route definition
.route(r -> r.before(LocalDateTime.now().atZone(ZoneId.systemDefault()))
.id("before_route")
.uri("http://example.com")

4.2. ルート述語ファクトリ間

Betweenルート述語ファクトリは、datetime1,datetime2の2つのパラメーターを取ります。 この述部は、datetime1(包括的)の後およびdatetime2(排他的)の前に発生する要求に一致します。 datetime2パラメータはdatetime1の後になければなりません:

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: http://example.com
        predicates:
        - Between=2017-09-10T17:42:47.789-07:00[America/Alaska], 2017-09-11T17:42:47.789-07:00[America/Alaska]

そして、Javaの構成は次のようになります。

ZonedDateTime datetime1 = LocalDateTime.now().minusDays(1).atZone(ZoneId.systemDefault());
ZonedDateTime datetime2 = LocalDateTime.now().atZone(ZoneId.systemDefault())
//..route definition
.route(r -> r.between(datetime1, datetime2))
.id("between_route")
.uri("http://example.com")

4.3. Header Route Predicate Factory

Headerルート述語ファクトリは、ヘッダー名と正規表現の2つのパラメーターを取ります。 この述部は、正規表現に一致するヘッダーに一致します。

spring:
  cloud:
    gateway:
      routes:
      - id: header_route
        uri: http://example.com
        predicates:
        - Header=X-Request-Id, \d+

Java構成は次のように表すことができます。

//..route definition
.route(r -> r.header("X-Request-Id", "\\d+")
.id("header_route")
.uri("http://example.com")

4.4. Hostルート述語係数

Hostルート述語ファクトリは1つのパラメータを取ります:ホスト名パターン。 このパターンは、区切り文字として「。」を使用したAntスタイルのパターンです。

この述語は、Hostヘッダーを指定されたパターンと一致させます。

spring:
  cloud:
    gateway:
      routes:
      - id: host_route
        uri: http://example.com
        predicates:
        - Host=**.example.com

Java構成の代替案は次のとおりです。

//..route definition
.route(r -> r.host("**.example.com")
.id("host_route")
.uri("http://example.com")

4.5. Method Route Predicate Factory

Methodルート述語ファクトリは1つのパラメータを取ります:一致するHTTPメソッド:

spring:
  cloud:
    gateway:
      routes:
      - id: method_route
        uri: http://example.com
        predicates:
        - Method=GET

Java構成は次のように表すことができます。

//..route definition
.route(r -> r.method("GET")
.id("method_route")
.uri("http://example.com")

4.6. Path Route Predicate Factory

Pathルート述語ファクトリは1つのパラメータを取ります:SpringPathMatcherパターン:

spring:
  cloud:
    gateway:
      routes:
      - id: path_route
        uri: http://example.com
        predicates:
        - Path=/articles/{articleId}

Java構成:

//..route definition
.route(r -> r.path("/articles/"+articleId)
.id("path_route")
.uri("http://example.com")

4.7. Query Route Predicate Factory

Queryルート述語ファクトリは2つのパラメータを取ります:必須パラメータとオプションの正規表現:

spring:
  cloud:
    gateway:
      routes:
      - id: query_route
        uri: http://example.com
        predicates:
        - Query=articleId, \w

Javaの構成:

//..route definition
.route(r -> r.query("articleId", "\w")
.id("query_route")
.uri("http://example.com")

4.8. RemoteAddr Route Predicate Factory

RemoteAddrルート述語ファクトリはCIDR表記文字列のリスト(最小1)を取得します(例:192.168.0.1/16(192.168.0.1はIPアドレス、16はサブネットマスク))。

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: http://example.com
        predicates:
        - RemoteAddr=192.168.1.1/24

対応するJava構成:

//..route definition
.route(r -> r.remoteAddr("192.168.1.1/24")
.id("remoteaddr_route")
.uri("http://example.com")

5. WebFilterファクトリ

ルートフィルタにより、着信HTTP要求または発信HTTP応答を変更できます。

Spring Cloud Gatewayには、多くのビルトインWebFilterファクトリが含まれています。

5.1. AddRequestHeaderWebFilterファクトリ

AddRequestHeader WebFilter Factoryは、名前と値のパラメーターを取ります。

spring:
  cloud:
    gateway:
      routes:
      - id: addrequestheader_route
        uri: http://example.com
        predicates:
        - Path=/articles
        filters:
        - AddRequestHeader=X-SomeHeader, bael

対応するJava構成は次のとおりです。

//...route definition
.route(r -> r.path("/articles")
  .filters(f -> f.addRequestHeader("X-TestHeader", "rewrite_request"))
  .uri("http://example.com")
  .id("addrequestheader_route")

5.2. AddRequestParameterWebFilterファクトリ

AddRequestParameter WebFilter Factoryは、名前と値のパラメーターを取ります。

spring:
  cloud:
    gateway:
      routes:
      - id: addrequestparameter_route
        uri: http://example.com
        predicates:
        - Path=/articles
        filters:
        - AddRequestParameter=foo, bar

対応するJava構成:

//...route definition
.route(r -> r.path("/articles")
  .filters(f -> f.addRequestParameter("foo", "bar"))
  .uri("http://example.com")
  .id("addrequestparameter_route")

5.3. AddResponseHeaderWebFilterファクトリ

AddResponseHeader WebFilter Factoryは、名前と値のパラメーターを取ります。

spring:
  cloud:
    gateway:
      routes:
      - id: addrequestheader_route
        uri: http://example.com
        predicates:
        - Path=/articles
        filters:
        - AddResponseHeader=X-SomeHeader, Bar

対応するJava構成:

//...route definition
.route(r -> r.path("/articles")
  .filters(f -> f.addResponseHeader("X-SomeHeader", "Bar"))
  .uri("http://example.com")
  .id("addresponseheader_route")

5.4.サーキットブレーカWebFilterファクトリ

HystrixはCircuit-Breaker WebFilter Factoryとして使用され、Hystrixコマンドの名前である単一の名前パラメーターを取ります。

spring:
  cloud:
    gateway:
      routes:
      - id: hystrix_route
        uri: http://example.com
        predicates:
        - Path=/articles
        filters:
        - Hystrix=someCommand

対応するJava構成:

//...route definition
.route(r -> r.path("/articles")
  .filters(f -> f.hystrix("some-command"))
  .uri("http://example.com")
  .id("hystrix_route")

5.5. RedirectToWebFilterファクトリ

RedirectTo WebFilter Factoryは、ステータスとURLパラメータを受け取ります。 ステータスは、301などの300リダイレクトHTTPコードである必要があります。

spring:
  cloud:
    gateway:
      routes:
      - id: redirectto_route
        uri: http://example.com
        predicates:
        - Path=/articles
        filters:
        - RedirectTo=302, http://foo.bar

対応するJava構成:

//...route definition
.route(r -> r.path("/articles")
  .filters(f -> f.redirect("302","http://foo.bar"))
  .uri("http://example.com")
  .id("redirectto_route")

5.6. RewritePathWebFilterファクトリ

RewritePath WebFilter Factoryは、パスregexpパラメーターと置換パラメーターを取ります。 これは、Java正規表現を使用してリクエストパスを書き換えます。

設定例を次に示します。

spring:
  cloud:
    gateway:
      routes:
      - id: rewritepath_route
        uri: http://example.com
        predicates:
        - Path=/articles/**
        filters:
        - RewritePath=/articles/(?.*), /$\{articleId}

Java構成は次のように表すことができます。

//...route definition
.route(r -> r.path("/articles")
  .filters(f -> f.rewritePath("(?.*)", articleId))
  .uri("http://example.com")
  .id("rewritepath_route")

5.7. RequestRateLimiterWebFilterファクトリ

RequestRateLimiter WebFilter Factoryは、replenishRate, capacity,keyResolverName.の3つのパラメーターを取ります。

  • replenishRateは、ユーザーに許可する1秒あたりのリクエスト数を表します

  • capacityは、許容されるバースト容量を定義します

  • keyResolverNameKeyResolverインターフェースを実装するBeanの名前です。

KeyResolverインターフェースにより、プラグ可能な戦略により、リクエストを制限するためのキーを導出できます。

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: http://example.com
        predicates:
        - Path=/articles
        filters:
        - RequestRateLimiter=10, 50, userKeyResolver

Java構成は次のように表すことができます。

//...route definition
.route(r -> r.path("/articles")
  .filters(f -> f.requestRateLimiter().configure(c -> c.setRateLimiter(myRateLimiter)))
  .uri("http://example.com")
  .id("requestratelimiter_route")

6. Spring CloudDiscoveryClientのサポート

Spring Cloud Gatewayは、Eureka ServerやConsulなどのService DiscoveryおよびRegistryライブラリと簡単に統合できます。

@Configuration
@EnableDiscoveryClient
public class GatewayDiscoveryConfiguration {

    @Bean
    public DiscoveryClientRouteDefinitionLocator
      discoveryClientRouteLocator(DiscoveryClient discoveryClient) {

        return new DiscoveryClientRouteDefinitionLocator(discoveryClient);
    }
}

6.1. LoadBalancerClientフィルター

LoadBalancerClientFilterは、ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR.を使用して交換属性プロパティでURIを検索します

URLにlbスキームがある場合(たとえば、lb://example-service))、Spring CloudLoadBalancerClientを使用して、名前(i.e., example-service)を実際のホストとポートに解決します。

変更されていない元のURLは、ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR属性に配置されます。

7. モニタリング

Spring Cloud Gatewayは、アプリケーションを監視するためのすぐに使えるサービスを提供する有名なSpring-BootライブラリであるActuator APIを利用します。

Actuator APIをインストールして構成すると、/gateway/エンドポイントにアクセスしてゲートウェイ監視機能を視覚化できます。

8. 実装

ここで、path述語を使用して、プロキシサーバーとしてSpring CloudGatewayを使用する簡単な例を作成します。

8.1. 依存関係

Spring Cloud Gatewayは現在、バージョン2.0.0.RC2のマイルストーンリポジトリにあります。 これは、ここで使用しているバージョンでもあります。

プロジェクトを追加するには、依存関係管理システムを使用します。


    
        
            org.springframework.cloud
            spring-cloud-gateway
            2.0.0.RC2
            pom
            import
        
    

次に、必要な依存関係を追加します。


    org.springframework.boot
    spring-boot-actuator


    org.springframework.boot
    spring-boot-starter-webflux


    org.springframework.cloud
    spring-cloud-starter-gateway

8.2. コード実装

次に、application.ymlファイルに単純なルーティング構成を作成します。

spring:
  cloud:
    gateway:
      routes:
      - id: example_route
        uri: http://example.com
        predicates:
        - Path=/example/
management:
  endpoints:
    web:
      exposure:
        include: "*'

そして、ゲートウェイアプリケーションコード:

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

アプリケーションの起動後、URL:“http://localhost/actuator/gateway/routes/example_route”にアクセスして、作成されたすべてのルーティング構成を確認できます。

{
    "id":"example_route",
    "predicates":[{
        "name":"Path",
        "args":{"_genkey_0":"/example"}
    }],
    "filters":[],
    "uri":"http://example.com",
    "order":0
}

相対URL:“/example”がルートとして構成されていることがわかります。**この例で構成されているように、URL“http://localhost/example”を押すと、「http://example.com」にリダイレクトされます。

9. 結論

この記事では、Spring Cloud Gatewayの一部である機能とコンポーネントのいくつかを検討しました。 この新しいAPIは、ゲートウェイとプロキシをサポートするためのすぐに使用できるツールを提供します。

ここに示されている例は、GitHub repositoryにあります。