Explorer la nouvelle passerelle Spring Cloud
1. Vue d'ensemble
Dans cet article, nous allons explorer les principales fonctionnalités du projetSpring Cloud Gateway, une nouvelle API basée sur Spring 5, Spring Boot 2 et Project Reactor.
L'outil fournit des mécanismes de routage prêts à l'emploi souvent utilisés dans les applications de microservices afin de masquer plusieurs services derrière une seule façade.
Pour une explication du modèle de passerelle sans le projet Spring Cloud Gateway, consultez nosprevious article.
2. Gestionnaire de routage
Se concentrant sur les demandes de routage, Spring Cloud Gateway transmet les demandes à un mappage de gestionnaire de passerelle, qui détermine ce qu'il convient de faire avec les demandes correspondant à un itinéraire spécifique.
Commençons par un exemple rapide de la façon dont le gestionnaire de passerelle résout les configurations d'itinéraire à l'aide deRouteLocator:
@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();
}
Remarquez comment nous avons utilisé les principaux blocs de construction de cette API:
-
Route – l'API principale de la passerelle. Il est défini par une identification (ID) donnée, une destination (URI) et un ensemble de prédicats et de filtres
-
Predicate – unPredicate – de Java 8 utilisé pour faire correspondre les requêtes HTTP à l'aide d'en-têtes, de méthodes ou de paramètres
-
Filter – un ressort standardWebFilter
3. Routage dynamique
Tout commeZuul, Spring Cloud Gateway fournit des moyens de routage des requêtes vers différents services.
La configuration de routage peut être créée en utilisant pur Java (RouteLocator, comme indiqué dans l'exemple de la section 2.1) ou en utilisant la configuration des propriétés:
spring:
application:
name: gateway-service
cloud:
gateway:
routes:
- id: example
uri: example.com
- id: myOtherRouting
uri: localhost:9999
4. Usines de routage
Spring Cloud Gateway fait correspondre les routes à l'aide de l'infrastructure Spring WebFluxHandlerMapping.
Il comprend également de nombreuses usines de prédicats de route intégrées. Tous ces prédicats correspondent à différents attributs de la requête HTTP. Les usines de prédicats de route multiples peuvent être combinées via le «et» logique.
La correspondance de route peut être appliquée par programme ou via un fichier de propriétés de configuration en utilisant un type différent de fabriques de prédicats de route.
4.1. Usine de prédicat de routeBefore
L'usine de prédicat de routeBefore prend un paramètre: adatetime. Ce prédicat correspond aux demandes qui se produisent avant ledatetime actuel:
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://example.com
predicates:
- Before=2017-09-11T17:42:47.789-07:00[America/Alaska]
La configuration Java peut être représentée comme suit:
//..route definition
.route(r -> r.before(LocalDateTime.now().atZone(ZoneId.systemDefault()))
.id("before_route")
.uri("http://example.com")
4.2. Entre l'usine de prédicat d'itinéraire
L'usine de prédicat de routeBetween prend deux paramètres:datetime1, etdatetime2. Ce prédicat correspond aux demandes qui se produisent aprèsdatetime1 (inclus) et avantdatetime2 (exclusif). Le paramètredatetime2 doit être aprèsdatetime1:
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]
Et la configuration Java ressemble à ceci:
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. Usine de prédicat de routeHeader
L'usine de prédicat de routeHeader prend deux paramètres: le nom de l'en-tête et une expression régulière. Ce prédicat correspond à un en-tête correspondant à l'expression régulière:
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://example.com
predicates:
- Header=X-Request-Id, \d+
La configuration Java peut être représentée comme suit:
//..route definition
.route(r -> r.header("X-Request-Id", "\\d+")
.id("header_route")
.uri("http://example.com")
4.4. Host Facteur de prédicat d'itinéraire
LaHost Route Predicate Factory prend un paramètre: le modèle de nom d'hôte. Le motif est un motif de style fourmi avec “.” Comme séparateur.
Ce prédicat correspond à l'en-têteHost avec le modèle donné:
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://example.com
predicates:
- Host=**.example.com
Voici l'alternative de configuration Java:
//..route definition
.route(r -> r.host("**.example.com")
.id("host_route")
.uri("http://example.com")
4.5. Usine de prédicat de routeMethod
LaMethod Route Predicate Factory prend un paramètre: la méthode HTTP à faire correspondre:
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://example.com
predicates:
- Method=GET
La configuration Java peut être représentée comme suit:
//..route definition
.route(r -> r.method("GET")
.id("method_route")
.uri("http://example.com")
4.6. Usine de prédicat de routePath
L'usine de prédicat de routePath prend un paramètre: un modèle SpringPathMatcher:
spring:
cloud:
gateway:
routes:
- id: path_route
uri: http://example.com
predicates:
- Path=/articles/{articleId}
La configuration Java:
//..route definition
.route(r -> r.path("/articles/"+articleId)
.id("path_route")
.uri("http://example.com")
4.7. Usine de prédicat de routeQuery
LaQuery Route Predicate Factory prend deux paramètres: un paramètre obligatoire et une expression rationnelle facultative:
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://example.com
predicates:
- Query=articleId, \w
Et la configuration Java:
//..route definition
.route(r -> r.query("articleId", "\w")
.id("query_route")
.uri("http://example.com")
4.8. Usine de prédicat de routeRemoteAddr
LaRemoteAddr Route Predicate Factory prend une liste (minimum de 1) de chaînes de notation CIDR, par exemple,192.168.0.1/16 (où 192.168.0.1 est une adresse IP et 16 est un masque de sous-réseau):
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://example.com
predicates:
- RemoteAddr=192.168.1.1/24
Et la configuration Java correspondante:
//..route definition
.route(r -> r.remoteAddr("192.168.1.1/24")
.id("remoteaddr_route")
.uri("http://example.com")
5. Usines WebFilter
Les filtres de route permettent la modification de la requête HTTP entrante ou de la réponse HTTP sortante.
Spring Cloud Gateway inclut de nombreuses usines WebFilter intégrées.
5.1. AddRequestHeaderWebFilter Usine
Le WebFilter Factory deAddRequestHeader prend un paramètre de nom et de valeur:
spring:
cloud:
gateway:
routes:
- id: addrequestheader_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- AddRequestHeader=X-SomeHeader, bael
Voici la configuration Java correspondante:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.addRequestHeader("X-TestHeader", "rewrite_request"))
.uri("http://example.com")
.id("addrequestheader_route")
5.2. Usine WebFilterAddRequestParameter
Le WebFilter Factory deAddRequestParameter prend un paramètre de nom et de valeur:
spring:
cloud:
gateway:
routes:
- id: addrequestparameter_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- AddRequestParameter=foo, bar
La configuration Java correspondante:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.addRequestParameter("foo", "bar"))
.uri("http://example.com")
.id("addrequestparameter_route")
5.3. Usine WebFilterAddResponseHeader
Le WebFilter Factory deAddResponseHeader prend un paramètre de nom et de valeur:
spring:
cloud:
gateway:
routes:
- id: addrequestheader_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- AddResponseHeader=X-SomeHeader, Bar
La configuration Java correspondante:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.addResponseHeader("X-SomeHeader", "Bar"))
.uri("http://example.com")
.id("addresponseheader_route")
5.4. DisjoncteurWebFilter Usine
Hystrix est utilisé comme Circuit-Breaker WebFilter Factory et prend un seul paramètre de nom, qui est le nom de la commande Hystrix:
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- Hystrix=someCommand
La configuration Java correspondante:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.hystrix("some-command"))
.uri("http://example.com")
.id("hystrix_route")
Usine WebFilter5.5. RedirectTo
La WebFilter Factory deRedirectTo prend un statut et un paramètre URL. Le statut doit être un code HTTP 300 de redirection, tel que 301:
spring:
cloud:
gateway:
routes:
- id: redirectto_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- RedirectTo=302, http://foo.bar
Et la configuration Java correspondante:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.redirect("302","http://foo.bar"))
.uri("http://example.com")
.id("redirectto_route")
5.6. Usine WebFilterRewritePath
La WebFilter Factory deRewritePath prend un paramètre de regexp de chemin et un paramètre de remplacement. Ceci utilise des expressions régulières Java pour réécrire le chemin de requête.
Voici un exemple de configuration:
spring:
cloud:
gateway:
routes:
- id: rewritepath_route
uri: http://example.com
predicates:
- Path=/articles/**
filters:
- RewritePath=/articles/(?.*), /$\{articleId}
La configuration Java peut être représentée comme suit:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.rewritePath("(?.*)", articleId))
.uri("http://example.com")
.id("rewritepath_route")
5.7. Usine WebFilterRequestRateLimiter
RequestRateLimiter WebFilter Factory prend trois paramètres:replenishRate, capacity, etkeyResolverName.
-
replenishRate– représente le nombre de requêtes par seconde que vous voulez qu'un utilisateur soit autorisé à faire
-
capacity– définit la capacité de rafale autorisée
-
keyResolverName - est le nom d'un bean qui implémente l'interfaceKeyResolver
L'interface KeyResolver permet aux stratégies enfichables de dériver la clé pour limiter les demandes:
spring:
cloud:
gateway:
routes:
- id: requestratelimiter_route
uri: http://example.com
predicates:
- Path=/articles
filters:
- RequestRateLimiter=10, 50, userKeyResolver
La configuration Java peut être représentée comme suit:
//...route definition
.route(r -> r.path("/articles")
.filters(f -> f.requestRateLimiter().configure(c -> c.setRateLimiter(myRateLimiter)))
.uri("http://example.com")
.id("requestratelimiter_route")
6. Prise en charge de Spring Cloud DiscoveryClient
Spring Cloud Gateway peut être facilement intégré aux bibliothèques Service Discovery et Registry, telles que Eureka Server et Consul:
@Configuration
@EnableDiscoveryClient
public class GatewayDiscoveryConfiguration {
@Bean
public DiscoveryClientRouteDefinitionLocator
discoveryClientRouteLocator(DiscoveryClient discoveryClient) {
return new DiscoveryClientRouteDefinitionLocator(discoveryClient);
}
}
6.1. FiltreLoadBalancerClient
LeLoadBalancerClientFilter recherche un URI dans la propriété d'attribut d'échange en utilisantServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR.
Si l'URL a un schémalb (par exemple,lb://example-service), elle utilisera Spring CloudLoadBalancerClient pour résoudre le nom(i.e., example-service) en un hôte et un port réels.
L'URL d'origine non modifiée est placée dans l'attributServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR.
7. surveillance
Spring Cloud Gateway utilise l’API Actuator, une bibliothèque bien connue de Spring-Boot, qui fournit plusieurs services prêts à l’emploi pour la surveillance de l’application.
Une fois l'API de l'actionneur installée et configurée, les fonctionnalités de surveillance de la passerelle peuvent être visualisées en accédant au point de terminaison/gateway/.
8. la mise en oeuvre
Nous allons maintenant créer un exemple simple d'utilisation de Spring Cloud Gateway en tant que serveur proxy à l'aide du prédicatpath.
8.1. Les dépendances
Spring Cloud Gateway se trouve actuellement dans le référentiel des jalons, sur la version 2.0.0.RC2. C'est également la version que nous utilisons ici.
Pour ajouter le projet, nous utiliserons le système de gestion des dépendances:
org.springframework.cloud
spring-cloud-gateway
2.0.0.RC2
pom
import
Ensuite, nous ajouterons les dépendances nécessaires:
org.springframework.boot
spring-boot-actuator
org.springframework.boot
spring-boot-starter-webflux
org.springframework.cloud
spring-cloud-starter-gateway
8.2. Implémentation du code
Et maintenant, nous créons une configuration de routage simple dans le fichierapplication.yml:
spring:
cloud:
gateway:
routes:
- id: example_route
uri: http://example.com
predicates:
- Path=/example/
management:
endpoints:
web:
exposure:
include: "*'
Et le code de l'application Gateway:
@SpringBootApplication
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
Après le démarrage de l'application, nous pouvons accéder à l'url:“http://localhost/actuator/gateway/routes/example_route” pour vérifier toute la configuration de routage créée:
{
"id":"example_route",
"predicates":[{
"name":"Path",
"args":{"_genkey_0":"/example"}
}],
"filters":[],
"uri":"http://example.com",
"order":0
}
Nous voyons que l'url relative:“/example” est configurée comme une route, ** donc en frappant l'url“http://localhost/example”, nous serons redirigés vers «http://example.com», comme cela a été configuré dans notre exemple.
9. Conclusion
Dans cet article, nous avons exploré certaines des fonctionnalités et des composants de Spring Cloud Gateway. Cette nouvelle API fournit des outils prêts à l'emploi pour la prise en charge des passerelles et des mandataires.
Les exemples présentés ici se trouvent dans nosGitHub repository.