Spring Cloud(二十一):Gateway 元数据,超时,跨域,HTTPS,监控,问题定位
Spring Cloud Gateway 网关除了核心的路由判断表达式(predicate :有的译为谓词)和过滤器外,还有一些其它的设置,以便于可以更好的配置和应用 Gateway。
例如,元数据配置,超时处理,跨域处理,HTTPS 安全配置,监控/指标 收集,问题定位等。可以添加一些全局配置,可以收集健康数据,便于快速定位问题等等。
元数据
可以通过使用元数据来给每个路由配置额外的参数(对所有路由起效的全局参数)。示例如下:
1 | spring: |
可以从 Exchange 中获取的元数据属性。如下示例:
1 | Route route = exchange.getAttribute(GATEWAY_ROUTE_ATTR); |
路由定义
SpringCloudGateway 的配置由 RouteDefinitionLocator
实例的集合驱动。下面所示 RouteDefinitionLocator
接口:
1 | public interface RouteDefinitionLocator { |
默认情况下,通过 Spring Boot’s @ConfigurationProperties
机制,一个 PropertiesRouteDefinitionLocator
会加载配置属性。
PropertiesRouteDefinitionLocator 继承自 RouteDefinitionLocator,在网关自动配置类 GatewayAutoConfiguration 中将其注册为了 Bean,注入了 GatewayProperties。
较早的配置示例均使用快捷方式,该快捷方式使用位置参数而不是命名参数。 以下两个示例是等效的:
1 | spring: |
对于网关的某些用法,属性是足够的,但是某些生产用例将从外部资源(例如 数据库)加载配置中受益。
未来的里程碑版本将基于 Spring Data Repositories(例如 Redis,MongoDB 和 Cassandra)使用 RouteDefinitionLocator
实现。
超时处理
Gateway 可以为所有**路由 **或 重写指定的路由配置 HTTP 超时(连接超时 和 响应超时)。
全局超时
配置全避局 HTTP 超时,有两个参数可配置:connect-timeout
和 response-timeout
。
- connect-timeout:必须指定位 毫秒(milliseconds)单位
- response-timeout:必须指定位 java.time.Duration 类型
全局 HTTP 超时示例:
1 | spring: |
前置路由超时
配置前置路由(per-route)超时,有两个参数可用:
- connect-timeout:必须指定为 毫秒 单位。
- response-timeout:必须指定为 毫秒 单位。
per-route http timeouts configuration via configuration
1 | spring: |
per-route timeouts configuration using Java DSL
1 | import static org.springframework.cloud.gateway.support.RouteMetadataUtils.CONNECT_TIMEOUT_ATTR; |
流式路由API
为了在 Java 中实现简单的配置,RouteLocatorBuilder
bean 包含了一个流式的API。如下示例:
1 | // static imports from GatewayFilters and RoutePredicates |
此样式还允许更多的自定义路由判断表达式(谓词断言)。通过 RouteDefinitionLocator
Bean 定义的判断表达式使用逻辑 and
进行组合。通过使用流式 Java API,可以在 Predicate 类上使用 and()
,or()
和 negate()
运算符。
DiscoveryClient Routes
DiscoveryClient 路由定义定位器
可以将网关配置为基于在 DiscoveryClient
兼容服务注册表中注册的服务(服务注册和服务发现)来创建路由。
要启用此配置,设置 spring.cloud.gateway.discovery.locator.enabled=true
,并确保在类路径上有一个 DiscoveryClient
实现(例如,Netflix Eureka,Consul,或 Zookeeper)且已启用。
为 DiscoveryClient 路由配置判断表达式和过滤器
默认情况下,Gateway 为使用 DiscoveryClient
创建的路由定义单个判断表达式(谓词)和过滤器。
默认判断表达式是用 /service ID/**
样式定义的路径判断表达式(path predicate ),其中 serviceId
来自DiscoveryClient 发现的服务的 ID。
默认过滤器是使用正则表达式 /serviceId/(?<remaining>.*)
和 /${remaining}
替换的重写路径过滤器(rewrite path filter)。在将请求转发到下游服务之前,将服务ID 从路径中剥离。
如果要自定义 DiscoveryClient
路由使用的 判断表达式 和 过滤器,设置 spring.cloud.gateway.discovery.locator.predicates[x]
和 spring.cloud.gateway.discovery.locator.filters[y]
,这样做时,如果要保留该功能(默认判断表达式和过滤器),则需要确保包含默认判断表达式和过滤器。如下示例:
1 | Path : |
注意:上面的配置来自官网,但属性名后的分隔符 :
应该为 =
。
跨域配置
可以配置 Gateway 控制跨域行为。全局 CORS
配置是一个 URL模式的 Map,配置类是 org.springframework.cloud.gateway.config.GlobalCorsProperties
,属性前缀是 spring.cloud.gateway.globalcors,属性名是 corsConfigurations
。 如下示例:
1 | spring: |
上面示例:CORS跨域请求配置是,允许来自 docs.spring.io 域名(主机)的所有 GET 请求,开放所有请求路径。
要为某些网关路由判断表达式(predicate:谓词)未处理的请求提供相同的 CORS 配置,设置spring.cloud.gateway.globalcors.add-To-simple-url-handler-mapping
属性设置为true
。若因路由判断表达式由于 HTTP 请求方式是 OPTIONS
而无法判断为 true
时,但又要支持 CORS 跨域请求,这非常有用。
TLS / SSL
网关可以通过遵循常规的 Spring server configuration 来监听 HTTPS 上的请求。如下所示:
application.yml
1 | server: |
可以将网关路由路由到 HTTP 和 HTTPS 后端。 如果要路由到 HTTPS 后端,则可以使用以下配置将网关配置为信任所有下游证书:
application.yml
1 | spring: |
使用不安全的信任管理器(trust manager)不适用于生产。 对于生产部署,可以使用以下配置为网关配置一组可以信任的已知证书:
application.yml
1 | spring: |
如果未为 Spring Cloud Gateway 提供受信任的证书,则使用默认的信任库(可以通过设置javax.net.ssl.trustStore
系统属性来覆盖它)。
TLS 握手
网关维护一个用于路由到后端的客户端池(client pool)。当通过 HTTPS 进行通信时,客户端发起 TLS 握手。许多超时与此握手关联。可以按如下方式配置这些超时(默认显示):
application.yml
1 | spring: |
Netty访问日志
要启用 响应式 Netty 访问日志,设置 -Dreactor.netty.http.server.accessLogEnabled=true
。
注意:必须是 Java 系统属性,而不是 Spring Boot 属性。
可以将日志记录系统(logging system)配置为具有单独的访问日志文件。 以下示例创建一个 Logback 配置:
1 | <appender name="accessLog" class="ch.qos.logback.core.FileAppender"> |
问题定位
使用 SpringCloudGateway 时可能出现的常见问题。
日志级别
Log Levels:以下 loggers 可能包含 DEBUG 和 TRACE 级别的有价值的故障排除信息:
- org.springframework.cloud.gateway
- org.springframework.http.server.reactive
- org.springframework.web.reactive
- org.springframework.boot.autoconfigure.web
- reactor.netty
- redisratelimiter
窃听:Wiretap
Reactor Netty HttpClient 和 HttpServer 可以启用窃听。 当将reactor.netty
日志级别设置为 DEBUG
或 TRACE
时,且开启了窃听,将开启信息的日志记录,例如,通过发送和接收的 header 和 body。
要启用 wiretap,需为 httpserver设置 spring.cloud.gateway.httpserver.wiretap=true;为 httpclient 设置spring.cloud.gateway.httpclient.wiretap=true。
开发人员指南
下面是写编写网关的自定义组件的基本指南。
自定义路由判断表达式工厂
要自定义路由判断表达式(Route Predicate),需要实现 RoutePredicateFactory
接口,可以继承一个名为 AbstractRoutePredicateFactory
的抽象类。
MyRoutePredicateFactory.java
1 | public class MyRoutePredicateFactory extends AbstractRoutePredicateFactory<HeaderRoutePredicateFactory.Config> { |
自定义 GatewayFilter工厂
要写一个 GatewayFilter
,必须实现 GatewayFilterFactory
。可以继承一个名为 AbstractGatewayFilterFactory
的抽象类。如下示例:
PreGatewayFilterFactory.java:前置过滤器
1 | public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> { |
PostGatewayFilterFactory.java:后置过滤器
1 | public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> { |
自定义全局过滤器
自定义全局过滤器(global filter),必须实现 GlobalFilter
接口,这会应用于所有请求的过滤。
下面示例全局前置和后置过滤器:
1 |
|
使用Spring MVC或Webflux构建一个简单的Gateway
注意:以下描述了替代样式的网关。不同于先前文档中的描述。
Spring Cloud Gateway 提供了一个名为 ProxyExchange 的实用对象。可以在常规 Spring web handler(Web 处理器)中使用它作为方法参数。
它通过镜像 HTTP 动词的方法来支持基本的下游 HTTP Exchange。对于 MVC,它还支持通过 forward() 方法转发到本地处理器。要使用 ProxyExchange
,需要类路径中引入正确的模块(spring-cloud-gateway-mvc
或spring-cloud-gateway-webflux
)。
以下 MVC 示例将 请求 代理到 /test
下游远程服务器:
1 |
|
下面是 Webflux 的一个相同的示例:
1 |
|
ProxyExchange 上的便捷方法使处理器(handler)方法可以发现并增强传入请求的 URI 路径。
例如,可能希望提取路径的后缀以将它们传递到下游:
1 |
|
网关处理程序方法可以使用 Spring MVC 和 Webflux 的所有功能。 结果,例如,可以注入请求标头和查询参数,并且可以使用映射批注中的声明来约束传入的请求。 更多参考 Spring MVC 中有关 @RequestMapping
的文档。
可以使用 ProxyExchange 上的header()
方法将 HTTP 头添加到下游服务的响应中。
还可以通过将映射器(mapper)添加到get()
方法(和其他方法)来操纵响应头(以及响应中您需要的任何其他内容)。 映射器是一种函数,它接受传入的 ResponseEntity
并将其转换并传出。
为不将**敏感头(sensitive)(默认为 cookie
和 authorization
)和代理(proxy)**(x-forwarded-*
)头传递到下游服务提供了一流支持。
Spring Cloud(二十一):Gateway 元数据,超时,跨域,HTTPS,监控,问题定位
http://blog.gxitsky.com/2020/03/19/SpringCloud-21-gateway-timeout-cors-reactor/