Erkundung des neuen Spring Cloud Gateways

Entdecken Sie das neue Spring Cloud Gateway

1. Überblick

In diesem Artikel werden die Hauptfunktionen desSpring Cloud Gateway-Projekts erläutert, einer neuen API, die auf Spring 5, Spring Boot 2 und Project Reactor basiert.

Das Tool bietet sofort einsatzbereite Routing-Mechanismen, die häufig in Microservices-Anwendungen verwendet werden, um mehrere Services hinter einer einzigen Fassade zu verbergen.

Eine Erklärung des Gateway-Musters ohne das Spring Cloud Gateway-Projekt finden Sie in unserenprevious article.

2. Routing-Handler

Das Spring Cloud Gateway konzentriert sich auf das Weiterleiten von Anforderungen und leitet Anforderungen an eine Gateway-Handlerzuordnung weiter. Diese legt fest, was mit Anforderungen geschehen soll, die einer bestimmten Route entsprechen.

Beginnen wir mit einem kurzen Beispiel, wie der Gateway-Handler Routenkonfigurationen mithilfe vonRouteLocator: auflöst

@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();
}

Beachten Sie, wie wir die Hauptbausteine ​​dieser API verwendet haben:

  • Route –ist die primäre API des Gateways. Es wird durch eine bestimmte Identifikation (ID), einen Zielort (URI) und eine Reihe von Prädikaten und Filtern definiert

  • Predicate – istPredicate – von Java 8, das zum Abgleichen von HTTP-Anforderungen mithilfe von Headern, Methoden oder Parametern verwendet wird

  • Filter – ist ein StandardfederWebFilter

3. Dynamisches Routing

Genau wieZuul bietet Spring Cloud Gateway Mittel zum Weiterleiten von Anforderungen an verschiedene Dienste.

Die Routing-Konfiguration kann mithilfe von reinem Java (RouteLocator, wie im Beispiel in Abschnitt 2.1 gezeigt) oder mithilfe der Eigenschaftenkonfiguration erstellt werden:

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

4. Routing-Fabriken

Spring Cloud Gateway vergleicht Routen mithilfe der Spring WebFluxHandlerMapping-Infrastruktur.

Es enthält auch viele integrierte Routenprädikat-Fabriken. Alle diese Prädikate stimmen mit verschiedenen Attributen der HTTP-Anforderung überein. Mehrere Route Predicate Factories können über das logische "und" kombiniert werden.

Die Routenanpassung kann sowohl programmgesteuert als auch über die Konfigurationseigenschaftendatei mithilfe eines anderen Typs von Routenprädikat-Factories angewendet werden.

4.1. Before Route Predicate Factory

Die Route Predicate Factory vonBeforeverwendet einen Parameter: adatetime. Dieses Prädikat stimmt mit Anforderungen überein, die vor den aktuellendatetime auftreten:

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

Die Java-Konfiguration kann wie folgt dargestellt werden:

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

4.2. Zwischen Route Predicate Factory

Die Route Predicate Factory vonBetweenverwendet zwei Parameter:datetime1, unddatetime2. Dieses Prädikat stimmt mit Anforderungen überein, die nachdatetime1 (einschließlich) und vordatetime2 (exklusiv) auftreten. Der Parameterdatetime2 muss nachdatetime1 liegen:

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]

Und die Java-Konfiguration sieht so aus:

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

Die Route Predicate Factory vonHeaderverwendet zwei Parameter: den Headernamen und einen regulären Ausdruck. Dieses Prädikat entspricht einem Header, der dem regulären Ausdruck entspricht:

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

Die Java-Konfiguration kann wie folgt dargestellt werden:

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

4.4. Host Routenprädikatfaktor

Die Route Predicate Factory vonHostverwendet einen Parameter: das Hostnamenmuster. Das Muster ist ein Ameisenmuster mit dem Trennzeichen „.“.

Dieses Prädikat stimmt mit dem Header vonHostmit dem angegebenen Muster überein:

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

Hier ist die Java-Konfigurationsalternative:

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

4.5. Method Route Predicate Factory

Die Route Predicate Factory vonMethodverwendet einen Parameter: die passende HTTP-Methode:

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

Die Java-Konfiguration kann wie folgt dargestellt werden:

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

4.6. Path Route Predicate Factory

Die Route Predicate Factory vonPathverwendet einen Parameter: ein Muster von SpringPathMatcher:

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

Die Java-Konfiguration:

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

4.7. Query Route Predicate Factory

Die Route Predicate Factory vonQueryverwendet zwei Parameter: einen erforderlichen Parameter und einen optionalen regulären Ausdruck:

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

Und die Java-Konfiguration:

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

4.8. RemoteAddr Route Predicate Factory

Die Route Predicate Factory vonRemoteAddrerstellt eine Liste (mindestens 1) von CIDR-Notationszeichenfolgen, z. B.192.168.0.1/16 (wobei 192.168.0.1 eine IP-Adresse und 16 eine Subnetzmaske ist):

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

Und die entsprechende Java-Konfiguration:

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

5. WebFilter-Fabriken

Routenfilter ermöglichen die Änderung der eingehenden HTTP-Anforderung oder der ausgehenden HTTP-Antwort.

Spring Cloud Gateway enthält viele integrierte WebFilter-Fabriken.

5.1. AddRequestHeaderWebFilter Fabrik

Die WebFilter Factory vonAddRequestHeaderverwendet einen Namen und einen Wertparameter:

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

Hier ist die entsprechende Java-Konfiguration:

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

5.2. AddRequestParameter WebFilter Factory

Die WebFilter Factory vonAddRequestParameterverwendet einen Namen und einen Wertparameter:

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

Die entsprechende Java-Konfiguration:

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

5.3. AddResponseHeader WebFilter Factory

Die WebFilter Factory vonAddResponseHeaderverwendet einen Namen und einen Wertparameter:

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

Die entsprechende Java-Konfiguration:

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

5.4. LeistungsschalterWebFilter Fabrik

Hystrix wird als WebFilter Factory für Leistungsschalter verwendet und verwendet einen einzelnen Namensparameter, den Namen des Hystrix-Befehls:

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

Die entsprechende Java-Konfiguration:

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

5.5. RedirectTo WebFilter Factory

Die WebFilter Factory vonRedirectTonimmt einen Status und einen URL-Parameter an. Der Status sollte ein 300-Umleitungs-HTTP-Code sein, z. B. 301:

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

Und die entsprechende Java-Konfiguration:

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

5.6. RewritePath WebFilter Factory

Die WebFilter Factory vonRewritePathverwendet einen Pfad-Regexp-Parameter und einen Ersetzungsparameter. Hierbei werden reguläre Java-Ausdrücke verwendet, um den Anforderungspfad neu zu schreiben.

Hier ist ein Konfigurationsbeispiel:

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

Die Java-Konfiguration kann wie folgt dargestellt werden:

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

5.7. RequestRateLimiter WebFilter Factory

Die RequestRateLimiter WebFilter Factory akzeptiert drei Parameter:replenishRate, capacity, undkeyResolverName.

  • replenishRate gibt an, wie viele Anforderungen pro Sekunde ein Benutzer ausführen darf

  • capacity definiert, wie viel Berstkapazität zulässig wäre

  • keyResolverName - ist der Name einer Bean, die dieKeyResolver-Schnittstelle implementiert

Die KeyResolver-Schnittstelle ermöglicht steckbare Strategien, um den Schlüssel zum Begrenzen von Anforderungen abzuleiten:

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

Die Java-Konfiguration kann wie folgt dargestellt werden:

//...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 Cloud DiscoveryClient-Unterstützung

Spring Cloud Gateway kann problemlos in Service Discovery- und Registrierungsbibliotheken wie Eureka Server und Consul integriert werden:

@Configuration
@EnableDiscoveryClient
public class GatewayDiscoveryConfiguration {

    @Bean
    public DiscoveryClientRouteDefinitionLocator
      discoveryClientRouteLocator(DiscoveryClient discoveryClient) {

        return new DiscoveryClientRouteDefinitionLocator(discoveryClient);
    }
}

6.1. LoadBalancerClient Filter

LoadBalancerClientFilter sucht mitServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. nach einem URI in der Eigenschaft Exchange-Attribut

Wenn die URL einlb-Schema hat (z. B.lb://example-service), verwendet sie die Spring CloudLoadBalancerClient, um den Namen(i.e., example-service) in einen tatsächlichen Host und Port aufzulösen.

Die unveränderte ursprüngliche URL wird in das AttributServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTReingefügt.

7. Überwachung

Spring Cloud Gateway verwendet die Actuator-API, eine bekannte Spring-Boot-Bibliothek, die verschiedene sofort einsatzbereite Dienste zur Überwachung der Anwendung bietet.

Sobald die Actuator-API installiert und konfiguriert ist, können die Gateway-Überwachungsfunktionen durch Zugriff auf den Endpunkt von/gateway/visualisiert werden.

8. Implementierung

Wir erstellen nun ein einfaches Beispiel für die Verwendung von Spring Cloud Gateway als Proxyserver unter Verwendung des Prädikatspath.

8.1. Abhängigkeiten

Das Spring Cloud Gateway befindet sich derzeit in Version 2.0.0.RC2 im Meilenstein-Repository. Dies ist auch die Version, die wir hier verwenden.

Um das Projekt hinzuzufügen, verwenden wir das Abhängigkeitsverwaltungssystem:


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

Als Nächstes fügen wir die erforderlichen Abhängigkeiten hinzu:


    org.springframework.boot
    spring-boot-actuator


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


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

8.2. Code-Implementierung

Und jetzt erstellen wir eine einfache Routing-Konfiguration in der Dateiapplication.yml:

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

Und der Gateway-Anwendungscode:

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

Nach dem Start der Anwendung können wir auf die URL“http://localhost/actuator/gateway/routes/example_route” zugreifen, um alle erstellten Routing-Konfigurationen zu überprüfen:

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

Wir sehen, dass die relative URL:“/example” als Route konfiguriert ist. Wenn Sie also die URL“http://localhost/example” treffen, werden wir zu "http://example.com" umgeleitet, wie in unserem Beispiel konfiguriert.

9. Fazit

In diesem Artikel haben wir einige der Funktionen und Komponenten von Spring Cloud Gateway untersucht. Diese neue API bietet sofort einsatzbereite Tools für die Gateway- und Proxy-Unterstützung.

Die hier vorgestellten Beispiele finden Sie in unserenGitHub repository.