探索新Spring云网关【翻译】

java技术文章

2019-07-09

151

0

1、概述

在这个章节中,我仅仅解释spring云网关项目的新特性,基于spring5、spring boot2和项目反应堆的新的API.

在微服务应用中,工具提供了一种盒子之外的路由机制,提供一种方法将多服务隐藏再单面之后。

这里有一个没有使用spring网关应用解释的网关模式应用,请查看该章节:previous article

2、路由控制

开始关注路由请求,spring云网关重定向请求到网关控制映射,决定哪一个请求匹配的路由该做什么。

让我们用一个简单的例子,解释RouteLocator怎样用路由控制解析路由配置。

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

注意,我们怎样使用这个API的构建模块:

Route --网关的主要API.它通过一个id、目标URL和一系列判断和过滤器定义。

Predicate--一个java8 Predicate's,决定使用那一个匹配请求包含的header、方法和参数。

Filter--一个标准的Spring WebFilter.

3、动态路由

仅仅像Zuul,Spring路由网关提供了路由请求到不同service的方法。

路由配置可以使用纯java(例如第2点中的RouteLocator)或者是配置文件。

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

4、路由工厂

spring网关路由使用spring webflux控制基础组件来匹配路由。它也也包括构建了许多路由判断工厂。所有这些判断匹配不同的HTTP请求属性。多路由判断工厂可以使用and逻辑进行组合。

路由匹配可以使用不同类型的路由判断工厂进行代码或者通过配置文件实现。

4.1、路由判断工厂之前

路由判断工厂之前是有一个参数:时间戳,这个判断匹配请求发生在当前时间之前。

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

用户java配置可以使用如下表现形式:

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

4.2、路由判断工厂之间

路由判断工厂采用两个参数:时间戳1和时间戳2.这个判断匹配请求发生在时间戳1之后,时间戳2之前。时间戳2参数必须在时间戳1之后。

spring:
  cloud:
    gateway:
      routes:
      - id: between_route
        uri: http://baeldung.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://baeldung.com")

4.3、路由判断工厂头部信息

头部路由工厂采用两个参数:头部名称和规则表达式。这个判断使用头部信息匹配规则表达式:

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

使用java配置可以表示如下:

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

4.4、服务器地址路由判断工厂

服务器地址路由判断工厂采用一个参数:服务器地址模式。这个模式是用一个逗号隔开ant样式模式。

这个判断用提供的模式匹配服务器头信息:

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

这里是供选择的java配置:

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

4.5、方法路由判断工厂

方法路由工厂采用一个参数:http方法去匹配:

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

使用java配置可以表示如下:

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

4.6、路径路由判断工厂

路径路由匹配工厂采用一个参数:一个spring路径匹配模式:

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

java配置如下:

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

4.7、查询路由判断工厂

查询路由判断工厂采用两个参数:一个需要的参数和传统的正则表达式:

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

使用java配置:

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

4.8、远程地址路由判断工厂

远程地址路由判断工厂采用一个CIDR字符穿列表,例如:192.168.0.1/16是一个ip地址,16是一个子网段。

spring:
  cloud:
    gateway:
      routes:
      - id: remoteaddr_route
        uri: http://baeldung.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://baeldung.com")

5、WebFilter工厂

路由过滤器可以修改进入的http请求或者是可能输出的http响应。

Spring cloud 网关包括了很多WebFilter工厂。

5.1、AddRequestHeader WebFilter 工厂

addRequestHeader WebFilter工厂使用一个名称和值参数。

spring:
  cloud:
    gateway:
      routes:
      - id: addrequestheader_route
        uri: http://baeldung.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://baeldung.com")
  .id("addrequestheader_route")

5.2、addRequestParamter WebFilter工厂

addRequestParamter WebFilter工厂采用一个名称和一个值参数。

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

相对应的java配置如下:

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

5.3、AddResponseHeader WelFilter工厂

AddResponseHeader WelFilter工厂采用一个名称和一个值参数:

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

相对应的java配置:

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

5.4、熔断WebFilter工厂

Hystrix采用一个熔断WebFilter工厂,使用一个Hystrix命令行作为单个参数。

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

相对应的java配置:

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

5.5、重定向WebFilter工厂

重定向WebFilter工厂采用一个状态和一个URL参数。状态码应该使用300作为重定向请求编码,例如301:

spring:
  cloud:
    gateway:
      routes:
      - id: redirectto_route
        uri: http://baeldung.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://baeldung.com")
  .id("redirectto_route")

5.6、RewritePath WelFilter工厂

RewritePath WelFilter工厂采用一个正则表达式参数和一个通配符做为参数。 这里使用java正则表达式重写请求路径。

这里是配置事例:

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

java对应的表现形式如下:

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

5.7、RequestRateLimiter WebFilter工厂

RequestRateLimiter WebFilter工厂采用3个参数:补充率、容量和keyResolverName。

补充率 --表示一秒中之内,多少个用户被允许请求。

容量--定义最大请求容量

keyResolverName--一个继承至KeyResolver接口的实体bean名称。

KeyResolver接口允许可插拔策略派生一个限制请求的key。

spring:
  cloud:
    gateway:
      routes:
      - id: requestratelimiter_route
        uri: http://baeldung.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://baeldung.com")
  .id("requestratelimiter_route")

6、spring网关DiscoveryClient 的支持

spring网关能容易的集成Discovery服务和注册库。例如:Eureka 服务和Consul

@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 scheme,将使用spring cloud中的LoadBalancerClient解释名称。

7、监控

spring Cloud网关确定使用Actuator API(一个总所周知的组件),提供对盒子之外的服务提供监控应用。

如果Actuator被安装并且配置,可以使用/gateway/端点访问网关特性。

8、实现

我们现在创建一个事例,使用Spring Cloud Gateway路径判断作为代理服务。

8.1、依赖

Spring Cloud网关当前里程碑的库版本号是2.0.0.RC2,这也是我们这里使用的版本。

我们使用 dependency management系统添加到项目中:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-gateway</artifactId>
            <version>2.0.0.RC2</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencyManagement>

接下来,我们添加必要的依赖包:

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

8.2、实现

现在我们再application.yml 文件中配置路由参数

spring:
  cloud:
    gateway:
      routes:
      - id: baeldung_route
        uri: http://baeldung.com
        predicates:
        - Path=/baeldung/
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/baeldung_route

获取路由的配置信息:

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

我们看到/baeldung作为一个路由配置,所以我们使用如下地址:

http://localhost/baeldung

访问,将会重定向到

http://baeldung.com

这是在我们的项目中进行配置的 。

9、结论

 在这个章节中,我们介绍了Spring Cloud网关部分特性和组件,新的API提供了盒子之外的工具对网关和代理进行支持。

项目代码可以在这里下载:GitHub repository.

 欢迎访问:www.hongfu951.com博客,查看更多技术文章

 

发表评论

全部评论:0条

鸿福951

努力打造一个好用的webui

热评文章

推荐文章