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.