概念
Gateway是基于異步非阻塞模型上進(jìn)行開發(fā)的疟位,有springcloud團(tuán)隊(duì)開發(fā)勋篓。用來代替Zuul。
內(nèi)容
Route(路由)
路由是構(gòu)建網(wǎng)關(guān)的基本模塊睡毒,它由ID,目標(biāo)URL冗栗,一系列的斷言和過濾器組成,如果斷言為true則匹配該路由
Predicate(斷言)
參考的是java8的java.util.function.Predicate
開發(fā)人員可以匹配HTTP請(qǐng)求中的所有內(nèi)容(例如請(qǐng)求頭或者請(qǐng)求參數(shù))供搀,如果請(qǐng)求與斷言想匹配則路由
Filter(過濾)
指的是Spring框架中GatewayFilter的實(shí)例隅居,使用過濾器,可以請(qǐng)求被路由器前或者之后對(duì)請(qǐng)求進(jìn)行修改
Zuul
Zuul1基于servlet阻塞I/O的API Gateway葛虐,且進(jìn)入維護(hù)
Zuul2雖然基于非阻塞I/O胎源,但是還沒有發(fā)布,且SpringCloud沒有整合
優(yōu)點(diǎn)
- 基于Spring Framework5, Project Reactor 和SpringBoot 2.0 進(jìn)行構(gòu)建
- 動(dòng)態(tài)路由:能夠匹配任何請(qǐng)求屬性
- 可以對(duì)路由指定Predicate(斷言) 和 Filter(過濾器)
- 繼承Hystrix的斷路器功能
- 集成SpringCloud服務(wù)發(fā)現(xiàn)功能
- 易于編寫的Predicate(斷言) 和 Filter(過濾器)
- 請(qǐng)求限流功能
- 支持路由重寫
作用
可以不對(duì)外開放服務(wù)端屿脐,只對(duì)外開放網(wǎng)關(guān)
Spring Cloud Gateway工作流程
使用
- 新建網(wǎng)關(guān)模型
- pom引入Gateway
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
- 將網(wǎng)關(guān)注冊(cè)進(jìn)eureka/Zookeeper/Consul
- 由yml網(wǎng)關(guān)配置涕蚤。在yml中加入
spring:
cloud:
gateway:
routes:
- id: payment_routh #路由的id宪卿,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
-url: http://localhost:8001 #匹配后提供服務(wù)的路由地址
-predicates:
- Path=/payment/get/** #斷言万栅,路徑相匹配的進(jìn)行路由
- id: payment_routh2 #路由的id佑钾,沒有固定規(guī)則但要求唯一,建議配合服務(wù)名
-url: http://localhost:8001 #匹配后提供服務(wù)的路由地址
-predicates:
- Path=/payment/1b/** #斷言烦粒,路徑相匹配的進(jìn)行路由
- 測(cè)試
在網(wǎng)關(guān)中休溶,不需要springboot的web和actuator,否則啟動(dòng)報(bào)錯(cuò)扰她。在pom中移除即可
--啟動(dòng)eureka/Zookeeper/Consul兽掰、網(wǎng)關(guān)、服務(wù)端
--通過網(wǎng)關(guān)訪問服務(wù)端 - 用代碼配置徒役,創(chuàng)建一個(gè)配置類
@Configuration
public class GatwayConfig{
@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder routeLocatorBuilder){
RouteLocatorBuilder.Builder routes = routeLocatorBuilder.routes();
routes .route("path_route",r -> r.path("/guonei").uri("http://baidu.com/guonei")).build();
return routes.build();
}
}
實(shí)現(xiàn)動(dòng)態(tài)路由功能
默認(rèn)情況下Gateway會(huì)根據(jù)注冊(cè)中心注冊(cè)的服務(wù)列表孽尽,以注冊(cè)中心上微服務(wù)名為路徑創(chuàng)建動(dòng)態(tài)路由進(jìn)行轉(zhuǎn)發(fā),從而實(shí)現(xiàn)動(dòng)態(tài)路由功能
實(shí)現(xiàn)
spring:
cloud:
gateway:
discovery:
locator:
enabled: true
routes:
- id: payment_routh #路由的id忧勿,沒有固定規(guī)則但要求唯一杉女,建議配合服務(wù)名
# -url: http://localhost:8001 #匹配后提供服務(wù)的路由地址
-url: 1b://cloud-payment-service
-predicates:
- Path=/payment/get/** #斷言,路徑相匹配的進(jìn)行路由
- id: payment_routh2 #路由的id狐蜕,沒有固定規(guī)則但要求唯一宠纯,建議配合服務(wù)名
#-url: http://localhost:8001 #匹配后提供服務(wù)的路由地址
-url: 1b://cloud-payment-service
-predicates:
- Path=/payment/1b/** #斷言,路徑相匹配的進(jìn)行路由
predicates的參數(shù).如下為官網(wǎng)內(nèi)容
- 所述After路線謂詞工廠有一個(gè)參數(shù)层释,一個(gè)datetime(其是Java ZonedDateTime)婆瓜。該謂詞匹配在指定日期時(shí)間之后發(fā)生的請(qǐng)求。下面的示例配置路由后謂詞:
例子1. application.yml
spring:
cloud:
gateway:
routes:
- id: after_route
uri: https://example.org
predicates:
- After=2017-01-20T17:42:47.789-07:00[America/Denver]
這條路線符合2017年1月20日17:42山區(qū)時(shí)間(丹佛)之后的任何請(qǐng)求贡羔。
- 獲取時(shí)區(qū)
ZonedDateTime zbj = ZonedDateTime.now();//默認(rèn)時(shí)區(qū)
System.out.println(zbj);
- 所述Before路線謂詞工廠有一個(gè)參數(shù)廉白,一個(gè)datetime(其是Java ZonedDateTime)。該謂詞匹配在指定之前發(fā)生的請(qǐng)求datetime乖寒。下面的示例配置路由前謂詞:
例子2. application.yml
spring:
cloud:
gateway:
routes:
- id: before_route
uri: https://example.org
predicates:
- Before=2017-01-20T17:42:47.789-07:00[America/Denver]
這條路線符合2017年1月20日山區(qū)時(shí)間(丹佛)之前的任何請(qǐng)求猴蹂。
- 該Between路線謂詞工廠有兩個(gè)參數(shù),datetime1并且datetime2 這是JavaZonedDateTime對(duì)象楣嘁。該謂詞匹配之后datetime1和之前發(fā)生的請(qǐng)求datetime2磅轻。該datetime2參數(shù)必須是后datetime1。以下示例配置了路由之間的謂詞:
例子3. application.yml
spring:
cloud:
gateway:
routes:
- id: between_route
uri: https://example.org
predicates:
- Between=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]
此路線與2017年1月20日山區(qū)時(shí)間(丹佛)之后和2017年1月21日17:42山區(qū)時(shí)間(丹佛)之后的任何請(qǐng)求相匹配逐虚。這對(duì)于維護(hù)時(shí)段可能很有用聋溜。
- 所述Cookie路線謂詞工廠采用兩個(gè)參數(shù),該cookiename和regexp(其是Java正則表達(dá)式)叭爱。該謂詞匹配具有給定名稱且其值與正則表達(dá)式匹配的cookie撮躁。以下示例配置cookie路由謂詞工廠:
例子4. application.yml
spring:
cloud:
gateway:
routes:
- id: cookie_route
uri: https://example.org
predicates:
- Cookie=chocolate, ch.p
此路由匹配具有名稱為chocolate與ch.p正則表達(dá)式匹配的cookie的請(qǐng)求。
- 所述Header路線謂詞工廠采用兩個(gè)參數(shù)买雾,報(bào)頭name和一個(gè)regexp(其是Java正則表達(dá)式)把曼。該謂詞與具有給定名稱的標(biāo)頭匹配杨帽,該標(biāo)頭的值與正則表達(dá)式匹配。以下示例配置標(biāo)頭路由謂詞:
例子5. application.yml
spring:
cloud:
gateway:
routes:
- id: header_route
uri: https://example.org
predicates:
- Header=X-Request-Id, \d+
如果請(qǐng)求具有名為X-Request-Id其值與\d+正則表達(dá)式匹配的標(biāo)頭(即嗤军,其值為一個(gè)或多個(gè)數(shù)字)注盈,則此路由匹配。
- 該
Host
路線謂詞工廠需要一個(gè)參數(shù):主機(jī)名的列表patterns
型雳。該模式是帶有.
分隔符的Ant樣式的模式当凡。謂詞與Host
匹配模式的標(biāo)頭匹配。以下示例配置主機(jī)路由謂詞:
例子6. application.yml
spring:
cloud:
gateway:
routes:
- id: host_route
uri: https://example.org
predicates:
- Host=**.somehost.org,**.anotherhost.org
{sub}.myhost.org
還支持URI模板變量(例如)纠俭。
如果請(qǐng)求具有這種路由匹配Host
用的頭值www.somehost.org
或beta.somehost.org
或www.anotherhost.org
沿量。
該謂詞提取URI模板變量(例如sub
,在前面的示例中定義的)作為名稱和值的映射冤荆,并ServerWebExchange.getAttributes()
使用中定義的鍵將其放在中ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
朴则。這些值可供工廠使用GatewayFilter
- 所述Method路線謂詞廠需要methods的參數(shù),它是一個(gè)或多個(gè)參數(shù):HTTP方法來匹配钓简。以下示例配置方法route謂詞:
例子7. application.yml
spring:
cloud:
gateway:
routes:
- id: method_route
uri: https://example.org
predicates:
- Method=GET,POST
如果請(qǐng)求方法是aGET或a乌妒,則此路由匹配POST。
- 該
Path
路線謂詞廠有兩個(gè)參數(shù):春天的列表PathMatcher
patterns
和所謂的可選標(biāo)志matchTrailingSlash
(默認(rèn)true
)外邓。以下示例配置路徑路由謂詞:
例子8. application.yml
spring:
cloud:
gateway:
routes:
- id: path_route
uri: https://example.org
predicates:
- Path=/red/{segment},/blue/{segment}
如果請(qǐng)求路徑為撤蚊,則此路由匹配,例如:/red/1
或/red/1/
或/red/blue
或/blue/green
损话。
如果matchTrailingSlash
設(shè)置為false
侦啸,則請(qǐng)求路徑/red/1/
將不匹配。
該謂詞提取URI模板變量(例如segment
丧枪,在前面的示例中定義的)作為名稱和值的映射光涂,并ServerWebExchange.getAttributes()
使用中定義的鍵將其放在中ServerWebExchangeUtils.URI_TEMPLATE_VARIABLES_ATTRIBUTE
。這些值可供工廠使用GatewayFilter
可以使用實(shí)用程序方法(稱為get)來簡(jiǎn)化對(duì)這些變量的訪問拧烦。下面的示例演示如何使用該get方法:
Map<String, String> uriVariables = ServerWebExchangeUtils.getPathPredicateVariables(exchange);
String segment = uriVariables.get("segment");
- 所述Query路線謂詞工廠采用兩個(gè)參數(shù):所要求的param和可選的regexp(其是Java正則表達(dá)式)忘闻。以下示例配置查詢路由謂詞:
例子9. application.yml
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=green
如果請(qǐng)求包含green查詢參數(shù),則前面的路由匹配恋博。
application.yml
spring:
cloud:
gateway:
routes:
- id: query_route
uri: https://example.org
predicates:
- Query=red, gree.
如果請(qǐng)求包含一個(gè)前述路線匹配red齐佳,其值相匹配的查詢參數(shù)gree.的regexp,所以green和greet將匹配债沮。
- 所述RemoteAddr路線謂詞工廠需要的列表(分鐘尺寸1) sources炼吴,其是CIDR的表示法(IPv4或IPv6)的字符串,如192.168.0.1/16(其中192.168.0.1是一個(gè)IP地址和16一個(gè)子網(wǎng)掩碼)秦士。以下示例配置一個(gè)RemoteAddr路由謂詞:
例子10. application.yml
spring:
cloud:
gateway:
routes:
- id: remoteaddr_route
uri: https://example.org
predicates:
- RemoteAddr=192.168.1.1/24
如果請(qǐng)求的遠(yuǎn)程地址為,則此路由匹配192.168.1.10永高。
- 該
Weight
路線謂詞工廠有兩個(gè)參數(shù):group
和weight
(一個(gè)int)隧土。權(quán)重是按組計(jì)算的提针。以下示例配置權(quán)重路由謂詞:
例子11. application.yml
spring:
cloud:
gateway:
routes:
- id: weight_high
uri: https://weighthigh.org
predicates:
- Weight=group1, 8
- id: weight_low
uri: https://weightlow.org
predicates:
- Weight=group1, 2
這條路線會(huì)將大約80%的流量轉(zhuǎn)發(fā)到weighthigh.org,將大約20%的流量轉(zhuǎn)發(fā)到weightlow.org曹傀。
Spring Cloud gateway的Filter
非自定義的簡(jiǎn)單辐脖,按照文檔配置即可
Spring Cloud gateway的Filte官方文檔
生命周期與種類
- 生命周期-Only Two
- pre
- post
- 種類 - Only Two
- GatewayFilter 單一的Filter
- GlobalFilter 全局的Filter
自定義過濾器
- 新建Gateway配置類,實(shí)現(xiàn)GlobalFilter,Ordered接口皆愉,內(nèi)容如下
@Component
public class GatewayConfig implements GlobalFilter,Ordered{
@Override
public Mono<Void> filter(ServerWebExchange exchange,GatewayFilterChain chain){//exchange可以獲取到請(qǐng)求信息嗜价,chain用來將新的請(qǐng)求發(fā)出到下一個(gè)過濾鏈
String name = exchange.getRequest().getQueryParams().getFilter("uname");
if(name == null){
...
}
return chain.filter(exchange);
}
//getOrder是順序
@Override
public int getOrder(){
...
return 0;
}
}