ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring Cloud Gateway中文文档十二至十九章(3.1.0)

2022-02-23 13:00:09  阅读:226  来源: 互联网

标签:spring Spring 路由 3.1 过滤器 org 至十 gateway cloud


Spring Cloud Gateway
3.1.0

12. Http超时配置

可以为所有路由配置 Http 超时(响应和连接),并为每个特定路由覆盖。

12.1. 全局超时

要配置全局 http 超时:
c o n n e c t − t i m e o u t \color{lightblue}{connect-timeout} connect−timeout 必须以毫秒为单位指定。
r e s p o n s e − t i m e o u t \color{lightblue}{response-timeout} response−timeout必须指定为 java.time.Duration

全局 http 超时示例

spring:
  cloud:
    gateway:
      httpclient:
        connect-timeout: 1000
        response-timeout: 5s

12.2. 每条路由超时

要配置每条路由超时:
c o n n e c t − t i m e o u t \color{lightblue}{connect-timeout} connect−timeout必须以毫秒为单位指定。
r e s p o n s e − t i m e o u t \color{lightblue}{response-timeout} response−timeout必须以毫秒为单位指定。

通过配置进行每条路由 http 超时配置

  • id: per_route_timeouts
    uri: https://example.org
    predicates:
    • name: Path
      args:
      pattern: /delay/{timeout}
      metadata:
      response-timeout: 200
      connect-timeout: 200

使用 Java DSL 的每条路由超时配置

import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR;
import static org.springframework.cloud.gateway.support.RouteMetadataUtils.RESPONSE_TIMEOUT_ATTR;

      @Bean
      public RouteLocator customRouteLocator(RouteLocatorBuilder routeBuilder){
         return routeBuilder.routes()
               .route("test1", r -> {
                  return r.host("*.somehost.org").and().path("/somepath")
                        .filters(f -> f.addRequestHeader("header1", "header-value-1"))
                        .uri("http://someuri")
                        .metadata(RESPONSE_TIMEOUT_ATTR, 200)
                        .metadata(CONNECT_TIMEOUT_ATTR, 200);
               })
               .build();
      }

response-timeout具有负值的 per-route将禁用全局response-timeout值。

      - id:per_route_timeouts
        网址:https://example.org
        谓词:
          - 名称:路径
            参数:
              模式:/延迟/{超时}
        元数据:
          响应超时:-1

12.3. 流畅的 Java 路由 API

为了允许在 Java 中进行简单配置,RouteLocatorBuilderbean 包含一个流式 API。下面的清单显示了它是如何工作的:

例 68.GatewaySampleApplication.java

// static imports from GatewayFilters and RoutePredicates
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder, ThrottleGatewayFilterFactory throttle) {
    return builder.routes()
            .route(r -> r.host("**.abc.org").and().path("/image/png")
                .filters(f ->
                        f.addResponseHeader("X-TestHeader", "foobar"))
                .uri("http://httpbin.org:80")
            )
            .route(r -> r.path("/image/webp")
                .filters(f ->
                        f.addResponseHeader("X-AnotherHeader", "baz"))
                .uri("http://httpbin.org:80")
                .metadata("key", "value")
            )
            .route(r -> r.order(-1)
                .host("**.throttle.org").and().path("/get")
                .filters(f -> f.filter(throttle.apply(1,
                        1,
                        10,
                        TimeUnit.SECONDS)))
                .uri("http://httpbin.org:80")
                .metadata("key", "value")
            )
            .build();
}

这种风格还允许更多的自定义断言。bean定义的断言RouteDefinitionLocator使用逻辑组合and。通过使用 fluent Java API,您可以在类上使用and()、or()和negate()运算符Predicate。

12.4. 路线DiscoveryClient定义定位器

您可以将网关配置为基于在DiscoveryClient兼容服务注册表中注册的服务创建路由。

要启用此功能,请设置spring.cloud.gateway.discovery.locator.enabled=true并确保DiscoveryClient实现(例如 Netflix Eureka、Consul 或 Zookeeper)在类路径上并启用。

12.4.1. DiscoveryClient为路由配置谓词和过滤器

默认情况下,网关为使用DiscoveryClient.

默认谓词是使用模式定义的路径谓词/serviceId/**,其中serviceId是来自DiscoveryClient.

默认过滤器是带有正则表达式/serviceId/?(?.*)和替换的重写路径过滤器/${remaining}。这会在请求被发送到下游之前从路径中去除服务 ID。

如果要自定义DiscoveryClient路由使用的谓词或过滤器,请设置spring.cloud.gateway.discovery.locator.predicates[x]和spring.cloud.gateway.discovery.locator.filters[y]。这样做时,如果要保留该功能,则需要确保包含前面显示的默认谓词和过滤器。以下示例显示了它的外观:

示例 69.application.properties

spring.cloud.gateway.discovery.locator.predicates[0].name:路径
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name:主机
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name:断路器
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name:重写路径
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/?(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"

13. Reactor Netty 访问日志

要启用 Reactor Netty 访问日志,请设置-Dreactor.netty.http.server.accessLogEnabled=true.

它必须是 Java 系统属性,而不是 Spring Boot 属性。
您可以将日志记录系统配置为具有单独的访问日志文件。以下示例创建一个 Logback 配置:

例 70.logback.xml

    <appender name="accessLog" class="ch.qos.logback.core.FileAppender">
        <file>access_log.log</file>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
    </appender>
    <appender name="async" class="ch.qos.logback.classic.AsyncAppender">
        <appender-ref ref="accessLog" />
    </appender>

    <logger name="reactor.netty.http.server.AccessLog" level="INFO" additivity="false">
        <appender-ref ref="async"/>
    </logger>

14.CORS配置

您可以配置网关来控制 CORS 行为。“全局” CORS 配置是 URL 模式到Spring FrameworkCorsConfiguration的映射。以下示例配置 CORS:

例 71.application.yml

spring:
  cloud:
    gateway:
      globalcors:
        cors-configurations:
          '[/**]':
            allowedOrigins: "https://docs.spring.io"
            allowedMethods:
            - GET

在前面的示例中,允许来自docs.spring.io所有 GET 请求路径的请求的 CORS 请求。

要为某些网关路由谓词未处理的请求提供相同的 CORS 配置,请将spring.cloud.gateway.globalcors.add-to-simple-url-handler-mapping属性设置为true. 当您尝试支持 CORS 预检请求并且您的路由谓词未评估为时,这很有用,true因为 HTTP 方法是options.

15.执行器 API

执行/gateway器端点允许您监视 Spring Cloud Gateway 应用程序并与之交互。要远程访问,必须在应用程序属性中启用并通过 HTTP 或 JMX 公开端点。以下清单显示了如何执行此操作:

示例 72.application.properties

management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway

15.1. 详细执行器格式

Spring Cloud Gateway 中添加了一种新的、更详细的格式。它为每个路由添加了更多详细信息,让您可以查看与每个路由关联的谓词和过滤器以及任何可用配置。以下示例配置/actuator/gateway/routes:

[
  {
    "predicate": "(Hosts: [**.addrequestheader.org] && Paths: [/headers], match trailing slash: true)",
    "route_id": "add_request_header_test",
    "filters": [
      "[[AddResponseHeader X-Response-Default-Foo = 'Default-Bar'], order = 1]",
      "[[AddRequestHeader X-Request-Foo = 'Bar'], order = 1]",
      "[[PrefixPath prefix = '/httpbin'], order = 2]"
    ],
    "uri": "lb://testservice",
    "order": 0
  }
]

默认情况下启用此功能。要禁用它,请设置以下属性:

示例 73.application.properties

spring.cloud.gateway.actuator.verbose.enabled=false

这将true在未来的版本中默认使用。

15.2. 检索路由过滤器

本节详细介绍如何检索路由过滤器,包括:

  • 全局过滤器
  • [网关路由过滤器]

15.2.1. 全局过滤器

要检索应用于所有路由的全局过滤器GET,请向/actuator/gateway/globalfilters. 生成的响应类似于以下内容:

{
  “org.spring framework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5 ”:10100,
  “o rg.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101 ”:10000,
  “或g.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650 ”:-1,
  " org.springframework.cloud.gateway.filter.ForwardRoutingFilter@10 6459d9": 2147483647,
  “ org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd 5e0”:2147483647,
  " org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71 d23": 0,
  “org.s pringframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea ”:2147483637,
  “ org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889 ”:2147483646
}

响应包含已到位的全局过滤器的详细信息。对于每个全局过滤器,都有过滤器对象的字符串表示形式(例如,org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5)和过滤器链中的相应顺序。}

15.2.2. 路由过滤器

要检索应用于路由的GatewayFilter工厂GET,请向/actuator/gateway/routefilters. 生成的响应类似于以下内容:

{
  “[ AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]”:空,
  “[ SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]”:空,
  “[ SaveSessionGatewayFilterFactory@4449b273 configClass = Object]”:空
}

响应包含GatewayFilter应用于任何特定路由的工厂的详细信息。对于每个工厂,都有对应对象的字符串表示形式(例如,[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object])。请注意,该null值是由于端点控制器的实现不完整,因为它试图设置对象在过滤器链中的顺序,这不适用于GatewayFilter工厂对象。

15.3. 刷新路由缓存

要清除路由缓存,POST请向/actuator/gateway/refresh. 该请求返回没有响应正文的 200。

15.4. 检索网关中定义的路由

要检索网关中定义的路由,GET请向/actuator/gateway/routes. 生成的响应类似于以下内容:

[{
  "route_id": "first_route",
  “路由对象”:{“谓词
    ”:“org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@1e9d7e7d ”,
    “过滤器”:[
      “OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory$$Lambda$436/674480275@6631ef72 , order =0}”
    ]
  },
  “订单”:0
},
{
  "route_id": "second_route",
  “路由对象”:{“谓词
    ”:“org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298 ”,
    “过滤器”:[]
  },
  “订单”:0
}]

响应包含网关中定义的所有路由的详细信息。下表描述了响应的每个元素(每个元素都是一个路由)的结构:

路径类型描述
route_idString路径Id
route_object.predicateObject断言
route_object.filtersArray路由过滤器
orderNumber序号

15.5。检索有关特定路线的信息
要检索有关单个路由的信息,GET请向/actuator/gateway/routes/{id}(例如,/actuator/gateway/routes/first_route)发出请求。生成的响应类似于以下内容:

{
  "id": "first_route",
  “谓词”:[{
    “名称”:“路径”,
    "args": {"_genkey_0":"/first"}
  }],
  “过滤器”:[],
  "uri": "https://www.uri-destination.org",
  “订单”:0
}

下表描述了响应的结构:

路径类型描述
idString路径Id
predicatesArray断言数组
filtersArray路由过滤器
uriStringuri
orderNumber序号

15.6.创建和删除特定路线

要创建路由,请使用指定路由字段的 JSON 正文POST发出请求(请参阅检索有关特定路由的信息)。/gateway/routes/{id_route_to_create}

要删除路线,DELETE请向/gateway/routes/{id_route_to_delete}.

15.7. 回顾:所有端点的列表

下表总结了 Spring Cloud Gateway 执行器端点(请注意,每个端点都有/actuator/gateway作为基本路径):

id方法描述
globalfiltersGET显示应用于路由的全局过滤器列表。
routefiltersGETGatewayFilter列表
refreshPOST清除路由缓存。
routesGET显示网关中定义的路由列表。
routes/{id}GET显示有关特定路线的信息。
routes/{id}GET向网关添加新路由。
routes/{id}DELETE从网关中删除现有路由。

15.8. 在多个网关实例之间共享路由

Spring Cloud Gateway 提供了两种RouteDefinitionRepository实现。第一个是 InMemoryRouteDefinitionRepository只存在于一个网关实例的内存中。这种类型的存储库不适合跨多个网关实例填充路由。

为了在 Spring Cloud Gateway 实例的集群中共享路由,RedisRouteDefinitionRepository可以使用。要启用这种存储库,必须将以下属性设置为 true:spring.cloud.gateway.redis-route-definition-repository.enabled 与 RedisRateLimiter Filter Factory 类似,它需要使用 spring-boot-starter-data-redis-reactive Spring Boot 启动器。

16. 故障排除

本节介绍使用 Spring Cloud Gateway 时可能出现的常见问题。

16.1. 日志级别

以下记录器可能在DEBUG和TRACE级别包含有价值的故障排除信息:

  • org.springframework.cloud.gateway

  • org.springframework.http.server.reactive

  • org.springframework.web.reactive

  • org.springframework.boot.autoconfigure.web

  • reactor.netty

  • redisratelimiter

16.2. 窃听

Reactor NettyHttpClient可以HttpServer启用窃听。与将reactor.netty日志级别设置为DEBUG或结合使用时TRACE,它可以记录信息,例如通过网络发送和接收的标头和正文。要启用窃听,请分别为和设置spring.cloud.gateway.httpserver.wiretap=true或。spring.cloud.gateway.httpclient.wiretap=trueHttpServerHttpClient

17. 开发者指南

这些是编写网关的一些自定义组件的基本指南。

17.1. 编写自定义路由谓词工厂

为了编写路由谓词,您需要将其实现RoutePredicateFactory为 bean。有一个AbstractRoutePredicateFactory可以扩展的抽象类。

MyRoutePredicateFactory.java

@Component
public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<MyRoutePredicateFactory.Config> {

    public MyRoutePredicateFactory() {
        super(Config.class);
    }

    @Override
    public Predicate<ServerWebExchange> apply(Config config) {
        // grab configuration from Config object
        return exchange -> {
            //grab the request
            ServerHttpRequest request = exchange.getRequest();
            //take information from the request to see if it
            //matches configuration.
            return matches(config, request);
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

17.2. 编写自定义 GatewayFilter 工厂

要编写GatewayFilter,您必须将其实现GatewayFilterFactory为 bean。您可以扩展一个名为AbstractGatewayFilterFactory. 以下示例显示了如何执行此操作:

示例 74. PreGatewayFilterFactory.java

@Component
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

    public PreGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            //If you want to build a "pre" filter you need to manipulate the
            //request before calling chain.filter
            ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
            //use builder to manipulate the request
            return chain.filter(exchange.mutate().request(builder.build()).build());
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

PostGatewayFilterFactory.java

@Component
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

    public PostGatewayFilterFactory() {
        super(Config.class);
    }

    @Override
    public GatewayFilter apply(Config config) {
        // grab configuration from Config object
        return (exchange, chain) -> {
            return chain.filter(exchange).then(Mono.fromRunnable(() -> {
                ServerHttpResponse response = exchange.getResponse();
                //Manipulate the response in some way
            }));
        };
    }

    public static class Config {
        //Put the configuration properties for your filter here
    }

}

17.2.1. 在配置中命名自定义过滤器和引用

自定义过滤器类名应以GatewayFilterFactory.

例如,要引用Something配置文件中命名的过滤器,该过滤器必须位于名为SomethingGatewayFilterFactory.

可以创建一个不带 GatewayFilterFactory后缀的网关过滤器,例如class AnotherThing. 此过滤器可以AnotherThing在配置文件中引用。这不是受支持的命名约定,并且在将来的版本中可能会删除此语法。请更新过滤器名称以使其符合要求。

17.3. 编写自定义全局过滤器

要编写自定义全局过滤器,您必须GlobalFilter将接口实现为 bean。这会将过滤器应用于所有请求。

以下示例分别显示了如何设置全局前置和后置过滤器:

@Bean
public GlobalFilter customGlobalFilter() {
    return (exchange, chain) -> exchange.getPrincipal()
        .map(Principal::getName)
        .defaultIfEmpty("Default User")
        .map(userName -> {
          //adds header to proxied request
          exchange.getRequest().mutate().header("CUSTOM-REQUEST-HEADER", userName).build();
          return exchange;
        })
        .flatMap(chain::filter);
}

@Bean
public GlobalFilter customGlobalPostFilter() {
    return (exchange, chain) -> chain.filter(exchange)
        .then(Mono.just(exchange))
        .map(serverWebExchange -> {
          //adds header to response
          serverWebExchange.getResponse().getHeaders().set("CUSTOM-RESPONSE-HEADER",
              HttpStatus.OK.equals(serverWebExchange.getResponse().getStatusCode()) ? "It worked": "It did not work");
          return serverWebExchange;
        })
        .then();
}

18. 使用 Spring MVC 或 Webflux 构建简单网关

下面描述了另一种风格的网关。先前的文档均不适用于以下内容。
Spring Cloud Gateway 提供了一个名为ProxyExchange. 您可以在常规 Spring Web 处理程序中将其用作方法参数。它通过镜像 HTTP 动词的方法支持基本的下游 HTTP 交换。使用 MVC,它还支持通过forward()方法转发到本地处理程序。要使用ProxyExchange,请在类路径中包含正确的模块(spring-cloud-gateway-mvc或spring-cloud-gateway-webflux)。

以下 MVC 示例将请求代理到/test下游到远程服务器:

@RestController
@SpringBootApplication
public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public ResponseEntity<?> proxy(ProxyExchange<byte[]> proxy) throws Exception {
        return proxy.uri(home.toString() + "/image/png").get();
    }

}

以下示例对 Webflux 执行相同的操作:

@RestController
@SpringBootApplication
public class GatewaySampleApplication {

    @Value("${remote.home}")
    private URI home;

    @GetMapping("/test")
    public Mono<ResponseEntity<?>> proxy(ProxyExchange<byte[]> proxy) throws Exception {
        return proxy.uri(home.toString() + "/image/png").get();
    }

}

上的便捷方法ProxyExchange使处理程序方法能够发现和增强传入请求的 URI 路径。例如,您可能希望提取路径的尾随元素以将它们传递到下游:

@GetMapping("/proxy/path/**")
public ResponseEntity<?> proxyPath(ProxyExchange<byte[]> proxy) throws Exception {
  String path = proxy.path("/proxy/path/");
  return proxy.uri(home.toString() + "/foos/" + path).get();
}

Spring MVC 和 Webflux 的所有特性都可用于网关处理程序方法。因此,您可以注入请求标头和查询参数,例如,您可以使用映射注释中的声明来约束传入请求。有关这些功能的更多详细信息,请参阅@RequestMappingSpring MVC 中的文档。

header()您可以使用on 上的方法将标头添加到下游响应中ProxyExchange。

get()您还可以通过向方法(和其他方法)添加映射器来操作响应标头(以及响应中您喜欢的任何其他内容)。映射器是一个Function接收传入ResponseEntity并将其转换为传出的映射器。

cookie为不向下游传递的“敏感”标头(默认情况下和authorization)和“代理”(x-forwarded-*)标头提供一流的支持。

19.配置属性

要查看所有 Spring Cloud Gateway 相关配置属性的列表,请参阅附录。

标签:spring,Spring,路由,3.1,过滤器,org,至十,gateway,cloud
来源: https://blog.csdn.net/huaya1127/article/details/123086776

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有