Gateway 其他配置


  1. 1. TLS / SSL

Spring Cloud Gateway使用HTTPS,是和普通的Spring boot服務配置是一樣的,比如:

application.yml.

1
2
3
4
5
6
7
server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12

Spring Cloud Gateway都可以路由轉給給http和HTTPS的下游后端服務,如果是路由去HTTPS后端服務,gateway像下面一樣配置信任所有下游服務:

application.yml.

1
2
3
4
5
6
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true

當然這種配置,線上生成環境還是不太適合的,所以gateway可以配置自己的信任的證書列表:

application.yml.

1
2
3
4
5
6
7
8
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem

Spring Cloud Gateway如果沒有配置信任證書列表,則會拿系統默認的證書庫(可以通過system property的javax.net.ssl.trustStore屬性來修改系統默認證書庫)。

TLS Handshake

當是用HTTPS來通訊時,http客戶端就需要初始化TLS握手連接了,所以就需要配置握手連接時的超時配置:

application.yml.

1
2
3
4
5
6
7
8
spring:
cloud:
gateway:
httpclient:
ssl:
handshake-timeout-millis: 10000
close-notify-flush-timeout-millis: 3000
close-notify-read-timeout-millis: 0

2. Configuration

Spring Cloud Gateway是通過一系列的RouteDefinitionLocator接口配置的,接口如下:

RouteDefinitionLocator.java.

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

默認情況下,PropertiesRouteDefinitionLocator會通過Spring Boot的@ConfigurationProperties機制來加載路由配置,比如下面的例子(一個使用了完整的配置,一個使用了快捷配置,前幾章也大量的用了這些配置):

application.yml.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
spring:
cloud:
gateway:
routes:
- id: setstatus_route
uri: http://example.org
filters:
- name: SetStatus
args:
status: 401
- id: setstatusshortcut_route
uri: http://www.google.com
filters:
- SetStatus=401

通常情況下,properties的配置就已經夠用的了,但也有一些人的需求是從外部源來加載配置文件,比如數據庫等,所以官方也承諾未來的版本會基於Spring Data Repositories實現Redis, MongoDB和Cassandra版本的RouteDefinitionLocator

2.1 Fluent Java Routes API

除了上面的配置文件配置外,也可以通過RouteLocatorBuilder的流式API來進行java實現配置。

GatewaySampleApplication.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
// 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")
)
.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")
)
.build();
}

這種用法就可以通過實行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,當然serviceIdDiscoveryClient里面的服務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
2
3
4
5
6
7
8
9
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: Hystrix
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}'"

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
2
3
4
5
6
7
8
9
10
11
12
13
<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>

4. CORS Configuration

gateway是支持CORS的配置,可以通過不同的URL規則匹配不同的CORS策略:

application.yml.

1
2
3
4
5
6
7
8
9
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "http://docs.spring.io"
allowedMethods:
- GET

有不熟悉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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {

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

@Override
public GatewayFilter apply(Config config) {
// 從config對象中獲取配置
return (exchange, chain) -> {
// 在這里做請求前的事情
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
//重新構造新的request
return chain.filter(exchange.mutate().request(request).build());
};
}

public static class Config {
// 設置配置
}

}

請求后做的是事情,可以如下實現:

PostGatewayFilterFactory.java.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {

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

@Override
public GatewayFilter apply(Config config) {
// 從config對象中獲取配置
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
// 在這里做請求后的操作實現
}));
};
}

public static class 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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM