-
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