spring cloud gateway系列教程目錄
- spring cloud gateway系列教程1—Route Predicate
- spring cloud gateway系列教程2——GatewayFilter_上篇
- spring cloud gateway系列教程2——GatewayFilter_下篇
- spring cloud gateway系列教程3—Global Filters
- spring cloud gateway系列教程4—其他配置
1. TLS / SSL
Spring Cloud Gateway使用HTTPS搁嗓,是和普通的Spring boot服務(wù)配置是一樣的腺逛,比如:
application.yml.
server:
ssl:
enabled: true
key-alias: scg
key-store-password: scg1234
key-store: classpath:scg-keystore.p12
key-store-type: PKCS12
Spring Cloud Gateway都可以路由轉(zhuǎn)給給http和HTTPS的下游后端服務(wù)棍矛,如果是路由去HTTPS后端服務(wù)够委,gateway像下面一樣配置信任所有下游服務(wù):
application.yml.
spring:
cloud:
gateway:
httpclient:
ssl:
useInsecureTrustManager: true
當(dāng)然這種配置怖现,線上生成環(huán)境還是不太適合的,所以gateway可以配置自己的信任的證書(shū)列表:
application.yml.
spring:
cloud:
gateway:
httpclient:
ssl:
trustedX509Certificates:
- cert1.pem
- cert2.pem
Spring Cloud Gateway如果沒(méi)有配置信任證書(shū)列表吊输,則會(huì)拿系統(tǒng)默認(rèn)的證書(shū)庫(kù)(可以通過(guò)system property的javax.net.ssl.trustStore
屬性來(lái)修改系統(tǒng)默認(rèn)證書(shū)庫(kù))季蚂。
TLS Handshake
當(dāng)是用HTTPS來(lái)通訊時(shí)扭屁,http客戶(hù)端就需要初始化TLS握手連接了料滥,所以就需要配置握手連接時(shí)的超時(shí)配置:
application.yml.
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是通過(guò)一系列的RouteDefinitionLocator
接口配置的幔欧,接口如下:
RouteDefinitionLocator.java.
public interface RouteDefinitionLocator {
Flux<RouteDefinition> getRouteDefinitions();
}
默認(rèn)情況下,PropertiesRouteDefinitionLocator
會(huì)通過(guò)Spring Boot的@ConfigurationProperties
機(jī)制來(lái)加載路由配置雁社,比如下面的例子(一個(gè)使用了完整的配置霉撵,一個(gè)使用了快捷配置徒坡,前幾章也大量的用了這些配置):
application.yml.
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的配置就已經(jīng)夠用的了喇完,但也有一些人的需求是從外部源來(lái)加載配置文件剥啤,比如數(shù)據(jù)庫(kù)等锦溪,所以官方也承諾未來(lái)的版本會(huì)基于Spring Data Repositories實(shí)現(xiàn)Redis, MongoDB和Cassandra版本的RouteDefinitionLocator
。
2.1 Fluent Java Routes API
除了上面的配置文件配置外刻诊,也可以通過(guò)RouteLocatorBuilder
的流式API來(lái)進(jìn)行java實(shí)現(xiàn)配置。
GatewaySampleApplication.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")
)
.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();
}
這種用法就可以通過(guò)實(shí)行Predicate<ServerWebExchange>
接口來(lái)定義更復(fù)雜的匹配規(guī)則亿昏,也可以用and()
、or()
和negate()
來(lái)組合不同的匹配規(guī)則彤断,靈活性會(huì)更大一點(diǎn)。
2.2 DiscoveryClient Route Definition Locator
通過(guò)服務(wù)發(fā)現(xiàn)客戶(hù)端DiscoveryClient
供炼,gateway可以基于注冊(cè)了的服務(wù)自動(dòng)創(chuàng)建路由袋哼。
只需要配置spring.cloud.gateway.discovery.locator.enabled=true
,以及引入DiscoveryClient
的maven依賴(lài)即可弟翘,如:Netflix Eureka, Consul or Zookeeper。
Configuring Predicates and Filters For DiscoveryClient Routes
默認(rèn)情況下gateway中的GatewayDiscoveryClientAutoConfiguration
以及定義了一個(gè)predicate和filter的了睛琳。
默認(rèn)的predicate是配置了/serviceId/**
路徑的path predicate,當(dāng)然serviceId
是DiscoveryClient
里面的服務(wù)id。
默認(rèn)的filter是配置了匹配參數(shù)/serviceId/(?<remaining>.*)
和替換參數(shù)/${remaining}
的rewrite path filter愿待,目的是將serviceId從path中去除掉仍侥,因?yàn)橄掠问遣恍枰摹?/p>
你也可以自定義DiscoveryClient
路由的predicate和filter患蹂,只需要設(shè)置spring.cloud.gateway.discovery.locator.predicates[x]
和spring.cloud.gateway.discovery.locator.filters[y]
即可,如下:
application.properties.
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是沒(méi)有打印access log的,但是底層的Reactor Netty是有的,在應(yīng)用啟動(dòng)命名中增加設(shè)置-Dreactor.netty.http.server.accessLogEnabled=true
來(lái)開(kāi)啟找都。
注:因?yàn)镽eactor Netty不是基于spring boot的,所以它并不會(huì)去spring boot的配置中獲取上面的配置嗡贺,所以只能在Java System Property中獲取诫睬。
可以在常用的日志系統(tǒng)中配置日志的打印文件和格式续徽,如logback的配置:
logback.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>
4. CORS Configuration
gateway是支持CORS的配置床绪,可以通過(guò)不同的URL規(guī)則匹配不同的CORS策略:
application.yml.
spring:
cloud:
gateway:
globalcors:
corsConfigurations:
'[/**]':
allowedOrigins: "http://docs.spring.io"
allowedMethods:
- GET
有不熟悉CORS的膀斋,可以看一下這篇介紹糊识。
5. Actuator API
Spring Cloud Gateway也可以配置actuator來(lái)監(jiān)控和操作一些功能點(diǎn),增加下面的配置即可:
application.properties.
management.endpoint.gateway.enabled=true # default value
management.endpoints.web.exposure.include=gateway
5.1 查看filter信息
5.1.1 Global Filters
使用GET
請(qǐng)求gateway地址/actuator/gateway/globalfilters
,就可以獲取類(lèi)似于下面的返回:
{
"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實(shí)例,包含了實(shí)例的toString()
和order
的keyvalue信息。
5.1.2 Route Filters
使用GET
請(qǐng)求gateway地址/actuator/gateway/routefilters
祭隔,就可以獲取類(lèi)似于下面的返回:
{
"[AddRequestHeaderGatewayFilterFactory@570ed9c configClass = AbstractNameValueGatewayFilterFactory.NameValueConfig]": null,
"[SecureHeadersGatewayFilterFactory@fceab5d configClass = Object]": null,
"[SaveSessionGatewayFilterFactory@4449b273 configClass = Object]": null
}
返回信息里面包含了gateway中可以提供使用的GatewayFilter factories 詳細(xì)信息屯仗,其中展示的是GatewayFilterFactory的實(shí)例toString()
打印桩撮,及配置類(lèi)。后面的null
是某些GatewayFilter factory實(shí)現(xiàn)問(wèn)題融师,本來(lái)是用來(lái)展示order
的,但是GatewayFilter factory沒(méi)有實(shí)現(xiàn)后控,就返回null
了。
5.2 路由緩存刷新
使用POST
請(qǐng)求gateway地址/actuator/gateway/refresh
,并返回http狀態(tài)碼為200,標(biāo)識(shí)刷新路由緩存成功。
5.3 查看路由定義信息
使用GET
請(qǐng)求gateway地址/actuator/gateway/routes
轻猖,獲取類(lèi)似下面的返回:
[{
"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
}]
上面對(duì)象的定義如下表:
key | value類(lèi)型 | value描述 |
---|---|---|
route_id |
String | 路由id. |
route_object.predicate |
Object | Route Predicate |
route_object.filters |
Array | GatewayFilter |
order |
Number | 路由順序 |
5.3.1 查看單個(gè)路由信息
如果是想只獲取單個(gè)路由信息,則使用GET
請(qǐng)求地址/actuator/gateway/routes/{id}
即可。
5.3.2 創(chuàng)建和刪除路由
創(chuàng)建路由,使用POST
請(qǐng)求,并附帶類(lèi)似下面的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
請(qǐng)求地址/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 | 展示單個(gè)路由信息 |
routes/{id} |
POST | 添加新的路由 |
routes/{id} |
DELETE | 移除路由 |
開(kāi)發(fā)指南
自定義GatewayFilter Factories
如果想自定義實(shí)現(xiàn)GatewayFilterFactory
跷跪,可以繼承AbstractGatewayFilterFactory
抽象類(lèi)。
比如如果想請(qǐng)求前做一些事情,可以類(lèi)似于下面的實(shí)現(xiàn):
**PreGatewayFilterFactory.java. **
public class PreGatewayFilterFactory extends AbstractGatewayFilterFactory<PreGatewayFilterFactory.Config> {
public PreGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// 從config對(duì)象中獲取配置
return (exchange, chain) -> {
// 在這里做請(qǐng)求前的事情
ServerHttpRequest.Builder builder = exchange.getRequest().mutate();
//重新構(gòu)造新的request
return chain.filter(exchange.mutate().request(request).build());
};
}
public static class Config {
// 設(shè)置配置
}
}
請(qǐng)求后做的是事情又厉,可以如下實(shí)現(xiàn):
PostGatewayFilterFactory.java.
public class PostGatewayFilterFactory extends AbstractGatewayFilterFactory<PostGatewayFilterFactory.Config> {
public PostGatewayFilterFactory() {
super(Config.class);
}
@Override
public GatewayFilter apply(Config config) {
// 從config對(duì)象中獲取配置
return (exchange, chain) -> {
return chain.filter(exchange).then(Mono.fromRunnable(() -> {
ServerHttpResponse response = exchange.getResponse();
// 在這里做請(qǐng)求后的操作實(shí)現(xiàn)
}));
};
}
public static class Config {
// 設(shè)置配置
}
}
以上就是spring cloud gateway的其他配置使用講解煌妈,如果想查看其他spring cloud gateway的案例和使用汰蜘,可以點(diǎn)擊查看