Spring Cloud Gateway—网关(二)

时间:2022-12-01 14:13:51

Spring Cloud Gateway—网关(二)

7. 全局过滤器

该接口具有与 相同的签名。 这些是有条件地应用于所有路由的特殊过滤器。​​GlobalFilter​​​​GatewayFilter​

此接口及其用法可能会在未来的里程碑版本中发生变化。

7.1. 全局过滤器和网关过滤器的组合排序

当请求与路由匹配时,筛选 Web 处理程序会将 的所有实例和所有特定于路由的实例添加到筛选器链中。 此组合筛选器链按接口排序,您可以通过实现方法进行设置。​​GlobalFilter​​​​GatewayFilter​​​​org.springframework.core.Ordered​​​​getOrder()​

由于Spring Cloud Gateway区分了过滤器逻辑执行的“前”和“后”阶段(请参阅其工作原理),因此优先级最高的过滤器是“前”阶段的第一个和“后”阶段的最后一个。

以下清单配置筛选器链:

例 59。示例配置.java

@Bean
public GlobalFilter customFilter() {
return new CustomGlobalFilter();
}

public class CustomGlobalFilter implements GlobalFilter, Ordered {

@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
log.info("custom global filter");
return chain.filter(exchange);
}

@Override
public int getOrder() {
return -1;
}
}

7.2. 转发路由过滤器

在交换属性中查找 URI。 如果 URL 有 ascheme(例如),它使用 Springto 处理请求。 请求 URL 的路径部分将被转发 URL 中的路径覆盖。 未修改的原始 URL 将追加到属性中的列表中。​​ForwardRoutingFilter​​​​ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR​​​​forward​​​​forward:///localendpoint​​​​DispatcherHandler​​​​ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR​

7.3.反应式负载均衡器客户端过滤器

在名为的交换属性中查找 URI。 如果 URL 具有方案(例如),它将使用春云将名称(在本例中)解析为实际主机和端口,并替换同一属性中的 URI。 未修改的原始 URL 将追加到属性中的列表中。 筛选器还会在属性中查找它是否相等。 如果是这样,则适用相同的规则。 以下清单配置:​​ReactiveLoadBalancerClientFilter​​​​ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR​​​​lb​​​​lb://myservice​​​​ReactorLoadBalancer​​​​myservice​​​​ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR​​​​ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR​​​​lb​​​​ReactiveLoadBalancerClientFilter​

例 60.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: myRoute
uri: lb://service
predicates:
- Path=/service/**

默认情况下,当找不到服务实例时,返回 ais 值。 您可以将网关配置为返回 aby 设置。​​ReactorLoadBalancer​​​​503​​​​404​​​​spring.cloud.gateway.loadbalancer.use404=true​

从覆盖中转出的价值 向网关发出的请求中指定的方案。 例如,如果请求进入网关但表明它不安全,则下游请求将被发出。 相反的情况也可以适用。 但是,在网关配置中为路由指定了 ifis,前缀将被去除,并且路由 URL 生成的方案将覆盖配置。​​isSecure​​​​ServiceInstance​​​​ReactiveLoadBalancerClientFilter​​​​HTTPS​​​​ServiceInstance​​​​HTTP​​​​GATEWAY_SCHEME_PREFIX_ATTR​​​​ServiceInstance​

网关支持所有负载均衡器功能。您可以在Spring Cloud Commons文档中阅读有关它们的更多信息。

7.4. 网络路由过滤器

如果位于交换属性中的 URL 具有主动脉方案,则 Netty 路由过滤器将运行。 它使用 Nettyto 发出下游代理请求。 响应放在 exchange 属性中,以便在以后的筛选器中使用。 (还有一个实验性执行相同的功能,但不需要Netty。​​ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR​​​​http​​​​https​​​​HttpClient​​​​ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR​​​​WebClientHttpRoutingFilter​

7.5. 网络写入响应过滤器

如果存在 Nettyin 交换属性,则运行。 它在所有其他筛选器完成后运行,并将代理响应写回网关客户端响应。 (还有一个实验性执行相同的功能,但不需要Netty。​​NettyWriteResponseFilter​​​​HttpClientResponse​​​​ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR​​​​WebClientWriteResponseFilter​

7.6.路由到请求网址过滤器

如果交换属性中有对象,则为theruns。 它基于请求 URI 创建一个新的 URI,但使用对象的 URI 属性进行更新。 新的 URI 放置在交换属性中。​​Route​​​​ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR​​​​RouteToRequestUrlFilter​​​​Route​​​​ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR​

如果 URI 具有方案前缀,例如,该方案将从 URI 中剥离并放置在 中以供稍后在筛选器链中使用。​​lb:ws://serviceid​​​​lb​​​​ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR​

7.7. Websocket 路由过滤器

如果位于交换属性中的 URL 具有主动脉方案,则运行 websocket 路由过滤器。它使用 Spring WebSocket 基础架构将 websocket 请求转发到下游。​​ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR​​​​ws​​​​wss​

您可以通过在 URI 前面加上前缀来对 websocket 进行负载平衡,例如。​​lb​​​​lb:ws://serviceid​

如果使用SockJS作为普通 HTTP 的回退,则应配置正常的 HTTP 路由以及 websocket 路由。

以下清单配置 websocket 路由筛选器:

例 61.应用程序.yml

spring:
cloud:
gateway:
routes:
# SockJS route
- id: websocket_sockjs_route
uri: http://localhost:3001
predicates:
- Path=/websocket/info/**
# Normal Websocket route
- id: websocket_route
uri: ws://localhost:3001
predicates:
- Path=/websocket/**

7.8. 网关指标过滤器

要启用网关指标,请将 spring-boot-starter-actuator 添加为项目依赖项。然后,默认情况下,只要属性未设置为 ,网关指标筛选器就会运行。此筛选器添加使用以下标记命名的计时器指标:​​spring.cloud.gateway.metrics.enabled​​​​false​​​​spring.cloud.gateway.requests​

  • ​routeId​​:路由 ID。
  • ​routeUri​​:API 路由到的 URI。
  • ​outcome​​:结果,按HttpStatus.Series 分类。
  • ​status​​:返回给客户端的请求的 HTTP 状态。
  • ​httpStatusCode​​:返回到客户端的请求的 HTTP 状态。
  • ​httpMethod​​:用于请求的 HTTP 方法。

此外,通过属性(默认情况下设置为 false),您可以使用标签激活额外的指标:​​spring.cloud.gateway.metrics.tags.path.enabled​

  • ​path​​:请求的路径。

然后,可以从中抓取这些指标,并且可以轻松地与Prometheus集成以创建Grafana仪表板。​​/actuator/metrics/spring.cloud.gateway.requests​

要启用普罗米修斯端点,请添加项目依赖项。​​micrometer-registry-prometheus​

7.9. 将交易所标记为路由

网关路由后,它会通过添加到交换属性来将该交换标记为“已路由”。将请求标记为已路由后,其他路由筛选器将不会再次路由该请求, 基本上跳过过滤器。您可以使用一些方便的方法将交易所标记为路由 或检查交换是否已路由。​​ServerWebExchange​​​​gatewayAlreadyRouted​

  • ​ServerWebExchangeUtils.isAlreadyRouted​​获取对象并检查它是否已被“路由”。ServerWebExchange
  • ​ServerWebExchangeUtils.setAlreadyRouted​​获取对象并将其标记为“路由”。ServerWebExchange

8. HttpHeadersFilters

HttpHeadersFilters在将请求发送到下游之前应用于请求,例如在。​​NettyRoutingFilter​

8.1. 转发标头过滤器

标头筛选器创建要发送到下游服务的标头。它将当前请求的标头、方案和端口添加到任何现有的标头中。​​Forwarded​​​​Forwarded​​​​Host​​​​Forwarded​

8.2. 删除跳跃跳头过滤器

标头筛选器从转发的请求中删除标头。删除的默认标头列表来自IETF。​​RemoveHopByHop​

默认删除的标头为:

  • 连接
  • 保持活力
  • 代理身份验证
  • 代理授权
  • 拖车
  • 传输编码
  • 升级

若要更改此设置,请将属性设置为要删除的标头名称列表。​​spring.cloud.gateway.filter.remove-hop-by-hop.headers​

8.3. 外部标头过滤器

标头筛选器创建各种转发器以发送到下游服务。它使用当前请求的标头,方案,端口和路径来创建各种标头。​​XForwarded​​​​X-Forwarded-*​​​​Host​

单个标头的创建可以通过以下布尔属性(默认为 true)控制:

  • ​spring.cloud.gateway.x-forwarded.for-enabled​
  • ​spring.cloud.gateway.x-forwarded.host-enabled​
  • ​spring.cloud.gateway.x-forwarded.port-enabled​
  • ​spring.cloud.gateway.x-forwarded.proto-enabled​
  • ​spring.cloud.gateway.x-forwarded.prefix-enabled​

附加多个标头可以通过以下布尔属性(默认为 true)控制:

  • ​spring.cloud.gateway.x-forwarded.for-append​
  • ​spring.cloud.gateway.x-forwarded.host-append​
  • ​spring.cloud.gateway.x-forwarded.port-append​
  • ​spring.cloud.gateway.x-forwarded.proto-append​
  • ​spring.cloud.gateway.x-forwarded.prefix-append​

9. TLS 和 SSL

网关可以按照通常的 Spring 服务器配置侦听 HTTPS 上的请求。 以下示例演示如何执行此操作:

例 62.应用程序.yml

server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12

您可以将网关路由路由到 HTTP 和 HTTPS 后端。 如果要路由到 HTTPS 后端,则可以使用以下配置将网关配置为信任所有下游证书:

例 63.应用程序.yml

spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true

使用不安全的信任管理器不适合生产。 对于生产部署,您可以使用一组已知证书配置网关,这些证书可以通过以下配置信任这些证书:

例 64.应用程序.yml

spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem

如果 Spring 云网关未配置受信任的证书,则使用默认的信任存储(您可以通过设置系统属性来覆盖该信任存储)。​​javax.net.ssl.trustStore​

9.1. TLS 握手

网关维护用于路由到后端的客户端池。 通过 HTTPS 进行通信时,客户端会启动 TLS 握手。 许多超时与此握手相关联。 您可以配置这些超时,可以按如下方式配置(显示默认值):

例 65.应用程序.yml

spring:
cloud:
gateway:
httpclient:
ssl:
handshake-timeout-millis: 10000
close-notify-flush-timeout-millis: 3000
close-notify-read-timeout-millis: 0

10. 配置

Spring Cloud Gateway 的配置由一组实例驱动。 以下清单显示了接口的定义:​​RouteDefinitionLocator​​​​RouteDefinitionLocator​

例 66。路由定义定位器.java

public interface RouteDefinitionLocator {
Flux<RouteDefinition> getRouteDefinitions();
}

默认情况下,使用 Spring Boot 的机制加载属性。​​PropertiesRouteDefinitionLocator​​​​@ConfigurationProperties​

前面的配置示例都使用使用位置参数而不是命名参数的快捷方式表示法。 以下两个示例是等效的:

例 67.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: setstatus_route
uri: https://example.org
filters:
- name: SetStatus
args:
status: 401
- id: setstatusshortcut_route
uri: https://example.org
filters:
- SetStatus=401

对于网关的某些用法,属性是足够的,但某些生产用例受益于从外部源(如数据库)加载配置。未来的里程碑版本将具有基于Spring Data Repository的实现,例如Redis,MongoDB和Cassandra。​​RouteDefinitionLocator​

10.1. 路由定义指标

要启用度量,请将弹簧-引导-启动器-执行器添加为项目依赖项。然后,默认情况下,只要属性设置为 ,指标就可用。将添加一个名为的仪表指标,其值是 的数量。此指标可从以下网址获得。​​RouteDefinition​​​​spring.cloud.gateway.metrics.enabled​​​​true​​​​spring.cloud.gateway.routes.count​​​​RouteDefinitions​​​​/actuator/metrics/spring.cloud.gateway.routes.count​

11. 路由元数据配置

您可以使用元数据为每个路由配置其他参数,如下所示:

例 68.应用程序.yml

spring:
cloud:
gateway:
routes:
- id: route_with_metadata
uri: https://example.org
metadata:
optionName: "OptionValue"
compositeObject:
name: "value"
iAmNumber: 1

您可以从交易所获取所有元数据属性,如下所示:

Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR);
// get all metadata properties
route.getMetadata();
// get a single metadata property
route.getMetadata(someKey);

12. Http超时配置

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

12.1. 全局超时

要配置全局 http 超时:
必须以毫秒为单位指定。
必须指定为 java.time.Duration​​connect-timeout​​​​response-timeout​

全局 HTTP 超时示例

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

12.2. 每路由超时

要配置每个路由超时:
必须以毫秒为单位指定。
必须以毫秒为单位指定。​​connect-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​​​​response-timeout​

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

12.3. 流畅的Java路由API

为了允许在Java中进行简单的配置,thebean包含一个流畅的API。 以下清单显示了它的工作原理:​​RouteLocatorBuilder​

例 69。网关示例应用程序.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();
}

此样式还允许使用更多自定义谓词断言。 由 bebean 定义的谓词使用逻辑进行组合。 通过使用流畅的Java API,您可以在类上使用,和运算符。​​RouteDefinitionLocator​​​​and​​​​and()​​​​or()​​​​negate()​​​​Predicate​

12.4.发现客户端路由定义定位器

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

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

12.4.1. 为Discovery客户端路由配置谓词和过滤器

默认情况下,网关定义单个谓词,并为使用 a 创建的路由进行筛选。​​DiscoveryClient​

默认谓词是用模式定义的路径谓词,其中 来自 的服务的 ID。​​/serviceId/**​​​​serviceId​​​​DiscoveryClient​

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

如果要自定义路由使用的谓词或筛选器,setand。 执行此操作时,如果要保留该功能,则需要确保包含前面显示的默认谓词和筛选器。 以下示例显示了它的外观:​​DiscoveryClient​​​​spring.cloud.gateway.discovery.locator.predicates[x]​​​​spring.cloud.gateway.discovery.locator.filters[y]​

例 70。应用程序属性

spring.cloud.gateway.discovery.locator.predicates[0].name: Path
spring.cloud.gateway.discovery.locator.predicates[0].args[pattern]: "'/'+serviceId+'/**'"
spring.cloud.gateway.discovery.locator.predicates[1].name: Host
spring.cloud.gateway.discovery.locator.predicates[1].args[pattern]: "'**.foo.com'"
spring.cloud.gateway.discovery.locator.filters[0].name: CircuitBreaker
spring.cloud.gateway.discovery.locator.filters[0].args[name]: serviceId
spring.cloud.gateway.discovery.locator.filters[1].name: RewritePath
spring.cloud.gateway.discovery.locator.filters[1].args[regexp]: "'/' + serviceId + '/?(?<remaining>.*)'"
spring.cloud.gateway.discovery.locator.filters[1].args[replacement]: "'/${remaining}'"

13. 反应堆网络访问日志

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

它必须是 Java 系统属性,而不是 Spring Boot 属性。

您可以将日志记录系统配置为具有单独的访问日志文件。以下示例创建回日志配置:

例 71。登录.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 配置是Spring FrameworkCorsConfiguration 的 URL 模式映射。 以下示例配置 CORS:

例 72.应用程序.yml

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

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

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

15. 执行器接口

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

例 73。应用程序属性

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
}
]

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

例 74。应用程序属性

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

这将默认为将来的版本。​​true​

15.2. 检索路由过滤器

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

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

15.2.1. 全局过滤器

要检索应用于所有路由的全局筛选器,请向 发出请求。生成的响应类似于以下内容:​​GET​​​​/actuator/gateway/globalfilters​

{
"org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5": 10100,
"org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@4f6fd101": 10000,
"org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@32d22650": -1,
"org.springframework.cloud.gateway.filter.ForwardRoutingFilter@106459d9": 2147483647,
"org.springframework.cloud.gateway.filter.NettyRoutingFilter@1fbd5e0": 2147483647,
"org.springframework.cloud.gateway.filter.ForwardPathFilter@33a71d23": 0,
"org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@135064ea": 2147483637,
"org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@23c05889": 2147483646
}

响应包含已部署的全局筛选器的详细信息。 对于每个全局筛选器,筛选器对象(例如,)都有一个字符串表示形式,以及筛选器链中的相应顺序。​​org.springframework.cloud.gateway.filter.ReactiveLoadBalancerClientFilter@77856cc5​

15.2.2. 路由过滤器

若要检索应用于路由的网关筛选器工厂,请向 发出请求。 生成的响应类似于以下内容:​​GET​​​​/actuator/gateway/routefilters​

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

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

15.3. 刷新路由缓存

要清除路由缓存,请向 发出请求。 请求返回不带响应正文的 200。​​POST​​​​/actuator/gateway/refresh​

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

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

[{
"route_id": "first_route",
"route_object": {
"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@1e9d7e7d",
"filters": [
"OrderedGatewayFilter{delegate=org.springframework.cloud.gateway.filter.factory.PreserveHostHeaderGatewayFilterFactory$$Lambda$436/674480275@6631ef72, order=0}"
]
},
"order": 0
},
{
"route_id": "second_route",
"route_object": {
"predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298",
"filters": []
},
"order": 0
}]

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

路径

类型

描述

​route_id​

字符串

路由 ID。

​route_object.predicate​

对象

路由谓词。

​route_object.filters​

数组

应用于路由的网关筛选器工厂。

​order​

路由顺序。

15.5. 检索有关特定路由的信息

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

{
"id": "first_route",
"predicates": [{
"name": "Path",
"args": {"_genkey_0":"/first"}
}],
"filters": [],
"uri": "https://www.uri-destination.org",
"order": 0
}

下表描述了响应的结构:

路径

类型

描述

​id​

字符串

路由 ID。

​predicates​

数组

路由谓词的集合。每个项目定义给定谓词的名称和参数。

​filters​

数组

应用于路由的筛选器集合。

​uri​

字符串

路由的目标 URI。

​order​

路由顺序。

15.6. 创建和删除特定路由

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

要删除路由,请向 发出请求。​​DELETE​​​​/gateway/routes/{id_route_to_delete}​

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

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

身份证

HTTP方法

描述

​globalfilters​

获取

显示应用于路由的全局筛选器的列表。

​routefilters​

获取

显示应用于特定工艺路线的工厂列表。​​GatewayFilter​

​refresh​

发布

清除路由缓存。

​routes​

获取

显示在网关中定义的路由列表。

​routes/{id}​

获取

显示有关特定路由的信息。

​routes/{id}​

发布

将新路由添加到网关。

​routes/{id}​

删除

从网关中删除现有路由。

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

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

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

16. 故障排除

本节介绍使用 Spring 云网关时可能出现的常见问题。

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. 窃听

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

17. 开发人员指南

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

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

为了编写路由谓词,您需要实现为 bean。有一个抽象类叫做你可以扩展。​​RoutePredicateFactory​​​​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. 编写自定义网关过滤器工厂

要编写 a,您必须实现为 bean。 您可以扩展名为 的抽象类。 以下示例演示如何执行此操作:​​GatewayFilter​​​​GatewayFilterFactory​​​​AbstractGatewayFilterFactory​

例 75。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​

例如,要引用名为 inin 配置文件的筛选器,筛选器 必须位于名为的类中。​​Something​​​​SomethingGatewayFilterFactory​

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

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

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

以下示例分别显示如何设置全局前置和后置筛选器:

@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提供了一个名为的实用程序对象。 您可以在常规的 Spring Web 处理程序中将其用作方法参数。 它通过镜像 HTTP 谓词的方法支持基本的下游 HTTP 交换。 使用 MVC,它还支持通过方法转发到本地处理程序。 若要使用 ,请在类路径中包含正确的模块(可选)。​​ProxyExchange​​​​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();
}

}

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

@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 的所有功能都可用于网关处理程序方法。 因此,例如,您可以注入请求标头和查询参数,并且可以使用映射注释中的声明来约束传入请求。 有关这些功能的更多详细信息,请参阅Spring MVC的文档。​​@RequestMapping​

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

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

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