Gateway 其他配置
-
1. TLS / SSL
Spring Cloud Gateway使用HTTPS,是和普通的Spring boot服务配置是一样的,比如:
application.yml.
1
|
server:
|
Spring Cloud Gateway都可以路由转给给http和HTTPS的下游后端服务,如果是路由去HTTPS后端服务,gateway像下面一样配置信任所有下游服务:
application.yml.
1
|
spring:
|
当然这种配置,线上生成环境还是不太适合的,所以gateway可以配置自己的信任的证书列表:
application.yml.
1
|
spring:
|
Spring Cloud Gateway如果没有配置信任证书列表,则会拿系统默认的证书库(可以通过system property的javax.net.ssl.trustStore
属性来修改系统默认证书库)。
TLS Handshake
当是用HTTPS来通讯时,http客户端就需要初始化TLS握手连接了,所以就需要配置握手连接时的超时配置:
application.yml.
1
|
spring:
|
2. Configuration
Spring Cloud Gateway是通过一系列的RouteDefinitionLocator
接口配置的,接口如下:
RouteDefinitionLocator.java.
1
|
public interface RouteDefinitionLocator {
|
默认情况下,PropertiesRouteDefinitionLocator
会通过Spring Boot的@ConfigurationProperties
机制来加载路由配置,比如下面的例子(一个使用了完整的配置,一个使用了快捷配置,前几章也大量的用了这些配置):
application.yml.
1
|
spring:
|
通常情况下,properties的配置就已经够用的了,但也有一些人的需求是从外部源来加载配置文件,比如数据库等,所以官方也承诺未来的版本会基于Spring Data Repositories实现Redis, MongoDB和Cassandra版本的RouteDefinitionLocator
。
2.1 Fluent Java Routes API
除了上面的配置文件配置外,也可以通过RouteLocatorBuilder
的流式API来进行java实现配置。
GatewaySampleApplication.java.
1
|
// static imports from GatewayFilters and RoutePredicates
|
这种用法就可以通过实行Predicate<ServerWebExchange>
接口来定义更复杂的匹配规则,也可以用and()
、or()
和negate()
来组合不同的匹配规则,灵活性会更大一点。
2.2 DiscoveryClient Route Definition Locator
通过服务发现客户端DiscoveryClient
,gateway可以基于注册了的服务自动创建路由。
只需要配置spring.cloud.gateway.discovery.locator.enabled=true
,以及引入DiscoveryClient
的maven依赖即可,如:Netflix Eureka, Consul or Zookeeper。
spring.cloud.gateway.discovery.locator.enabled:启用了自动根据服务ID建立路由,路由的路径对应会使用大写ID(我用的版本里默认是小写的),若想要使用小写ID,可将spring.cloud.gateway.discovery.locator.lowerCaseServiceId设为true;在设置中也开放了gateway端点。必要时,可以使用RouteLocator实现自定义路由的方式。配置为true后,接下来启动相关服务,启动Spring Cloud Gateway,默认会跑在Netty上,如果测试请求/actuator/gateway/routes的话,就可以看到以下:
[ { "route_id": "CompositeDiscoveryClient_ACCTSVI", "route_definition": { "id": "CompositeDiscoveryClient_ACCTSVI", "predicates": [ { "name": "Path", "args": { "pattern": "/acctsvi/**" } } ], "filters": [ { "name": "RewritePath", "args": { "regexp": "/acctsvi/(?<remaining>.*)", "replacement": "/${remaining}" } } ], "uri": "lb://ACCTSVI", "order": 0 }, "order": 0 }, ... ]
每个路由设定会有个route_id作为识别,在路由定义的predicates中,可以看到设置了Path,这是Spring Cloud Gateway内建的断言器工厂Bean名称,pattern这个设置表示对于http://localhost:5555/acctsvi/xxxx的请求会转给uri设定的值:lb://ACCTSVI,也就是说路由转给了服务ID为ACCTSVI的服务。
filters中设置了RewritePath,这是个过滤器工厂Bean名称,依照regexp的规则,会捕捉请求中的/acctsvi/之后的部份,套用至服务的URI上,也就是http://localhost:5555/acctsvi/xxxx的请求,将会路由转发至http://acctsvi-uri/xxxx。
predicates与filters是Spring Cloud Gateway的重要特性,predicates断言哪些路径符合路由定义,filters设置具体哪些路径适用什么样的具体过滤器,除了设置之外,必要时,都可以代码自己定义。
Configuring Predicates and Filters For DiscoveryClient Routes
默认情况下gateway中的GatewayDiscoveryClientAutoConfiguration
以及定义了一个predicate和filter的了。
默认的predicate是配置了/serviceId/**
路径的path predicate,当然serviceId
是DiscoveryClient
里面的服务id。
默认的filter是配置了匹配参数/serviceId/(?<remaining>.*)
和替换参数/${remaining}
的rewrite path filter,目的是将serviceId从path中去除掉,因为下游是不需要的。
你也可以自定义DiscoveryClient
路由的predicate和filter,只需要设置spring.cloud.gateway.discovery.locator.predicates[x]
和spring.cloud.gateway.discovery.locator.filters[y]
即可,如下:
application.properties.
1
|
|
3. Reactor Netty Access Logs
spring cloud gateway是没有打印access log的,但是底层的Reactor Netty是有的,在应用启动命名中增加设置-Dreactor.netty.http.server.accessLogEnabled=true
来开启。
注:因为Reactor Netty不是基于spring boot的,所以它并不会去spring boot的配置中获取上面的配置,所以只能在Java System Property中获取。
可以在常用的日志系统中配置日志的打印文件和格式,如logback的配置:
logback.xml.
1
|
<appender name="accessLog" class="ch.qos.logback.core.FileAppender">
|
4. CORS Configuration
gateway是支持CORS的配置,可以通过不同的URL规则匹配不同的CORS策略:
application.yml.
1
|
spring:
|
有不熟悉CORS的,可以看一下这篇介绍。
5. Actuator API
Spring Cloud Gateway也可以配置actuator来监控和操作一些功能点,增加下面的配置即可:
前提:
management.endpoint.gateway.enabled=true # default value management.endpoints.web.exposure.include=gateway
5.1 查看filter信息
5.1.1 Global Filters
使用GET
请求gateway地址/actuator/gateway/globalfilters
,就可以获取类似于下面的返回:
{ "org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@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 }
返回信息包含了gateway的使用中的global filters实例,包含了实例的toString()
和order
的keyvalue信息。
5.1.2 Route Filters
使用GET
请求gateway地址/actuator/gateway/routefilters
,就可以获取类似于下面的返回:
{ "[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null, "[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null, "[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null }
返回信息里面包含了gateway中可以提供使用的GatewayFilter factories 详细信息,其中展示的是GatewayFilterFactory的实例toString()打印,及配置类。后面的null是某些GatewayFilter factory实现问题,本来是用来展示order的,但是GatewayFilter factory没有实现,就返回null了。
5.2 路由缓存刷新
使用POST
请求gateway地址/actuator/gateway/refresh
,并返回http状态码为200,标识刷新路由缓存成功。
5.3 查看路由定义信息
5.3.1 查看单个路由信息
如果是想只获取单个路由信息,则使用GET
请求地址/actuator/gateway/routes/{id}
即可。
5.3.2 查看所有路由信息
使用GET
请求gateway地址/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 }]
上面对象的定义如下表:
key | value类型 | value描述 |
---|---|---|
route_id |
String | 路由id. |
route_object.predicate |
Object | Route Predicate |
route_object.filters |
Array | GatewayFilter |
order |
Number | 路由顺序 |
5.3.3 创建和删除路由
创建路由,使用POST
请求,并附带类似下面的json body,到/gateway/routes/{id_route_to_create}
即可。
{ "route_id": "second_route", "route_object": { "predicate": "org.springframework.cloud.gateway.handler.predicate.PathRoutePredicateFactory$$Lambda$432/1736826640@cd8d298", "filters": [] }, "order": 0 }
删除路由,使用DELETE
请求地址/gateway/routes/{id_route_to_delete}
即可。
5.4 Actuator API汇总
ID | HTTP Method | Description |
---|---|---|
globalfilters |
GET | 展示global filters信息 |
routefilters |
GET | 展示GatewayFilter factories信息 |
refresh |
POST | 刷新路由缓存 |
routes |
GET | 展示路由定义信息 |
routes/{id} |
GET | 展示单个路由信息 |
routes/{id} |
POST | 添加新的路由 |
routes/{id} |
DELETE | 移除路由 |
开发指南
自定义GatewayFilter Factories
如果想自定义实现GatewayFilterFactory
,可以继承AbstractGatewayFilterFactory
抽象类。
比如如果想请求前做一些事情,可以类似于下面的实现:
*PreGatewayFilterFactory.java. *
1
|
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
|
请求后做的是事情,可以如下实现:
PostGatewayFilterFactory.java.
1
|
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
|
以上就是spring cloud gateway的其他配置使用讲解,如果想查看其他spring cloud gateway的案例和使用,可以点击查看
转自:https://www.edjdhbb.com/2019/01/09/spring-cloud-gateway%E7%B3%BB%E5%88%97%E6%95%99%E7%A8%8B4%E2%80%94%E5%85%B6%E4%BB%96%E9%85%8D%E7%BD%AE/
spring.cloud.gateway.discovery.locator.enabled