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—其他配置
怎么引入spring cloud gateway
maven上,只需引入如下依賴即可:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
引入了依賴默認(rèn)即開啟gateway了,如果暫時(shí)不想使用這個(gè)功能,這可以配置spring.cloud.gateway.enabled=false
即可。
Spring Cloud Gateway使用的是Spring Boot和Spring Webflux提供的Netty底層環(huán)境,不能和傳統(tǒng)的Servlet容器一起使用,也不能打包成一個(gè)WAR包。
工作原理
當(dāng)客戶端發(fā)送請(qǐng)求到Spring Cloud Gateway,Gateway Handler Mapping會(huì)匹配Route映射分發(fā)到Gateway Web Handler。handler會(huì)將請(qǐng)求經(jīng)過一系列的filter處理,代理請(qǐng)求前,會(huì)執(zhí)行左右的"pre" filter邏輯,代理請(qǐng)求后,會(huì)執(zhí)行所有"post" filter邏輯。
Route Predicate Factories
Spring Cloud Gateway是使用Spring WebFlux的HandlerMapping作為匹配路由底層實(shí)現(xiàn),本身已自帶很多Route Predicate Factories,分別匹配不同的http請(qǐng)求屬性,多個(gè)Route Predicate Factories也可以通過and
進(jìn)行邏輯合并匹配。
1. After Route Predicate Factory
After Route Predicate Factory使用的是時(shí)間作為匹配規(guī)則,只要當(dāng)前時(shí)間大于設(shè)定時(shí)間,路由才會(huì)匹配請(qǐng)求。
application.yml:
spring:
cloud:
gateway:
routes:
- id: after_route
uri: http://www.google.com
predicates:
- After=2018-12-25T14:33:47.789+08:00
這個(gè)路由規(guī)則會(huì)在東8區(qū)的2018-12-25 14:33:47后,將請(qǐng)求都轉(zhuǎn)跳到google。
2. Before Route Predicate Factory
Before Route Predicate Factory也是使用時(shí)間作為匹配規(guī)則,只要當(dāng)前時(shí)間小于設(shè)定時(shí)間,路由才會(huì)匹配請(qǐng)求。
application.yml:
spring:
cloud:
gateway:
routes:
- id: before_route
uri: http://www.google.com
predicates:
- Before=2018-12-25T14:33:47.789+08:00
這個(gè)路由規(guī)則會(huì)在東8區(qū)的2018-12-25 14:33:47前,將請(qǐng)求都轉(zhuǎn)跳到google。
3. Between Route Predicate Factory
Between Route Predicate Factory也是使用兩個(gè)時(shí)間作為匹配規(guī)則,只要當(dāng)前時(shí)間大于第一個(gè)設(shè)定時(shí)間,并小于第二個(gè)設(shè)定時(shí)間,路由才會(huì)匹配請(qǐng)求。
application.yml:
spring:
cloud:
gateway:
routes:
- id: between_route
uri: http://www.google.com
predicates:
- Between=2018-12-25T14:33:47.789+08:00, 2018-12-26T14:33:47.789+08:00
這個(gè)路由規(guī)則會(huì)在東8區(qū)的2018-12-25 14:33:47到2018-12-26 14:33:47之間,將請(qǐng)求都轉(zhuǎn)跳到google。
4. Cookie Route Predicate Factory
Cookie Route Predicate Factory使用的是cookie名字和正則表達(dá)式的value作為兩個(gè)輸入?yún)?shù),請(qǐng)求的cookie需要匹配cookie名和符合其中value的正則。
application.yml:
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: http://www.google.com
predicates:
- Cookie=cookiename, cookievalue
路由匹配請(qǐng)求存在cookie名為cookiename,cookie內(nèi)容匹配cookievalue的,將請(qǐng)求轉(zhuǎn)發(fā)到google。
5. Header Route Predicate Factory
Header Route Predicate Factory,與Cookie Route Predicate Factory類似,也是兩個(gè)參數(shù),一個(gè)header的name,一個(gè)是正則匹配的value。
application.yml:
spring:
cloud:
gateway:
routes:
- id: header_route
uri: http://www.google.com
predicates:
- Header=X-Request-Id, \d+
路由匹配存在名為X-Request-Id
,內(nèi)容為數(shù)字的header的請(qǐng)求,將請(qǐng)求轉(zhuǎn)發(fā)到google。
6. Host Route Predicate Factory
Host Route Predicate Factory使用的是host的列表作為參數(shù),host使用Ant style匹配。
application.yml:
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://www.google.com
predicates:
- Host=**.somehost.org,**.anotherhost.org
路由會(huì)匹配Host諸如:www.somehost.org
或 beta.somehost.org
或www.anotherhost.org
等請(qǐng)求。
7. Method Route Predicate Factory
Method Route Predicate Factory是通過HTTP的method來匹配路由。
application.yml:
spring:
cloud:
gateway:
routes:
- id: method_route
uri: http://www.google.com
predicates:
- Method=GET
路由會(huì)匹配到所有GET方法的請(qǐng)求。
8. Path Route Predicate Factory
Path Route Predicate Factory使用的是path列表作為參數(shù),使用Spring的PathMatcher
匹配path,可以設(shè)置可選變量。
application.yml:
spring:
cloud:
gateway:
routes:
- id: host_route
uri: http://www.google.com
predicates:
- Path=/foo/{segment},/bar/{segment}
上面路由可以匹配諸如:/foo/1
或 /foo/bar
或 /bar/baz
等
其中的segment變量可以通過下面方式獲取:
PathMatchInfo variables = exchange.getAttribute(URI_TEMPLATE_VARIABLES_ATTRIBUTE);
Map<String, String> uriVariables = variables.getUriVariables();
String segment = uriVariables.get("segment");
在后續(xù)的GatewayFilter Factories就可以做對(duì)應(yīng)的操作了。
9. Query Route Predicate Factory
Query Route Predicate Factory可以通過一個(gè)或兩個(gè)參數(shù)來匹配路由,一個(gè)是查詢的name,一個(gè)是查詢的正則value。
application.yml:
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://www.google.com
predicates:
- Query=baz
路由會(huì)匹配所有包含baz
查詢參數(shù)的請(qǐng)求。
application.yml:
spring:
cloud:
gateway:
routes:
- id: query_route
uri: http://www.google.com
predicates:
- Query=foo, ba.
路由會(huì)匹配所有包含baz
,并且baz
的內(nèi)容為諸如:bar
或baz
等符合ba.
正則規(guī)則的請(qǐng)求。
10. RemoteAddr Route Predicate Factory
RemoteAddr Route Predicate Factory通過無類別域間路由(IPv4 or IPv6)列表匹配路由。
application.yml:
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: http://www.google.com
predicates:
- RemoteAddr=192.168.1.1/24
上面路由就會(huì)匹配RemoteAddr諸如192.168.1.10
等請(qǐng)求。
10.1 Modifying the way remote addresses are resolved
RemoteAddr Route Predicate Factory默認(rèn)情況下,使用的是請(qǐng)求的remote address。但是如果Spring Cloud Gateway是部署在其他的代理后面的,如Nginx,則Spring Cloud Gateway獲取請(qǐng)求的remote address是其他代理的ip,而不是真實(shí)客戶端的ip。
考慮到這種情況,你可以自定義獲取remote address的處理器RemoteAddressResolver
。當(dāng)然Spring Cloud Gateway也提供了基于X-Forwarded-For請(qǐng)求頭的XForwardedRemoteAddressResolver
。
熟悉Http代理協(xié)議的,都知道X-Forwarded-For頭信息做什么的,不熟悉的可以自己谷歌了解一下。
XForwardedRemoteAddressResolver
提供了兩個(gè)靜態(tài)方法獲取它的實(shí)例:
XForwardedRemoteAddressResolver::trustAll
得到的RemoteAddressResolver
總是獲取X-Forwarded-For的第一個(gè)ip地址作為remote address,這種方式就比較容易被偽裝的請(qǐng)求欺騙,模擬請(qǐng)求很容易通過設(shè)置初始的X-Forwarded-For
頭信息,就可以欺騙到gateway。
XForwardedRemoteAddressResolver::maxTrustedIndex
得到的RemoteAddressResolver
則會(huì)在X-Forwarded-For
信息里面,從右到左選擇信任最多maxTrustedIndex
個(gè)ip,因?yàn)?code>X-Forwarded-For是越往右是越接近gateway的代理機(jī)器ip,所以是越往右的ip,信任度是越高的。
那么如果前面只是擋了一層Nginx的話,如果只需要Nginx前面客戶端的ip,則maxTrustedIndex
取1,就可以比較安全地獲取真實(shí)客戶端ip。
使用java的配置:
GatewayConfig.java:
RemoteAddressResolver resolver = XForwardedRemoteAddressResolver
.maxTrustedIndex(1);
...
.route("direct-route",
r -> r.remoteAddr("10.1.1.1", "10.10.1.1/24")
.uri("http://www.google.com")
.route("proxied-route",
r -> r.remoteAddr(resolver, "10.10.1.1", "10.10.1.1/24")
.uri("http://www.google.com")
)
這一章節(jié)講的了幾種Route Predicate Factory的使用及場(chǎng)景,下一章節(jié)講GatewayFilter Factories的使用。
如果想查看其他spring cloud gateway的案例和使用,可以點(diǎn)擊查看