一、filter的作用和生命周期
Zuul1.x 阻塞式IO 2.x 基於Netty,Spring Cloud GateWay天生就是異步非阻塞的,基於Reactor模型;
一個請求-->網關根據特定的條件匹配—>匹配成功之后可以將請求轉發到指定的服務地址;在這個過程中,我們可以進行一些比較具體的控制(限流、日志、黑白名單)
路由(route): 網關最基礎的部分,也是網關比較基礎的工作單元。路由由多個ID、多個多標URL(最終路由到的地址)、一系列的斷言(匹配條件判斷)和Filter過濾器(精細化控制)組成。如果斷言為true,則匹配該路由。
斷言(predicates):參考了Java8中的斷言java.util.function.Predicate,開發人員可以匹配Http請求中的所有內容(包括請求頭、請求參數等)(類似於nginx中的location匹配),如果斷言與請求相匹配則路由。
過濾器(filter):一個標准的Spring webFilter,使用過濾器,可以在請求之前或者之后執行業務邏輯。
Predicates斷言就是我們的匹配條件,Filter就可以理解為多個無所不能的攔截器,有了這兩個元素,結合⽬標URL,就可以實現一個具體的路由轉發。
1.1、作用
在微服務的上一層加一個全局的權限控制、限流、日志輸出的Api Gatewat服務,然后再將請求轉發到具體的業務服務層。這個Api Gateway服務就是起到一個服務邊界的作用,外接的請求訪問系統,必須先通過網關層。
1.2、生命周期
Spring Cloud Gateway同zuul類似,有“pre”和“post”兩種方式的filter。
![]()
|
|
客戶端向Spring Cloud GateWay發出請求,然后在GateWay Handler Mapping中找到與請求相匹配的路由,將其發送到GateWay Web Handler;Handler再通過指定的過濾器鏈來將請求發送到我們實際的服務執行業務邏輯,然后返回。過濾器之間用虛線分開是因為過濾器可能會在發送代理請求之前(pre)或者之后(post)執行業務邏輯。
Filter在“pre”類型過濾器中可以做參數校驗、權限校驗、流量監控、日志輸出、協議轉換等,在“post”類型的過濾器中可以做響應內容、響應頭的修改、日志的輸出、流量監控等。
從過濾器生命周期(影響時機點)的⻆度來說,主要有兩個pre和post:
- pre:這種過濾器在請求被路由之前調用。我們可以利用這類過濾器實現身份驗證、在集群中選擇 請求的微服務、記錄調試信息等。
- post:這種過濾器在路由到微服務以后執行。這類過濾器可用來為響應添加標准的HTTP Header、收集統計信息和指標、將響應從微服務發送給客戶端。
與zuul不同的是,filter除了分為“pre”和“post”兩種方式的filter外,在Spring Cloud Gateway中,
從過濾器作用范圍的角度來說,可分為另外兩種,一種是針對於單個路由的gateway filter,它在配置文件中的寫法同predict類似;另外一種是針對於所有路由的global gateway filer。現在從作用范圍划分的維度來講解這兩種filter。
區別:
- GatewayFilter:網關過濾器,需要通過spring.cloud.routes.filters配置在具體的路由下,只作用在當前特定路由上,也可以通過配置spring.cloud.default-filters讓它作用於全局路由上。
- GlobalFilter:全局過濾器,不需要再配置文件中配置,作用在所有的路由上,最終通過GatewayFilterAdapter包裝成GatewayFilterChain能夠識別的過濾器。
二、gateway filter
GatewayFilter : 需要通過spring.cloud.routes.filters 配置在具體路由下,只作用在當前路由上或通過spring.cloud.default-filters配置在全局,作用在所有路由上。
2.1、gateway內置的filter
2.2、自定義filter
2.2.1、自定義過濾器工廠
在上面的自定義過濾器中,有沒有辦法自定義過濾器工廠類呢?這樣就可以在配置文件中配置過濾器了。現在需要實現一個過濾器工廠,在打印時間的時候,可以設置參數來決定是否打印請參數。查看GatewayFilterFactory的源碼,可以發現GatewayFilterfactory的層級如下:
過濾器工廠的頂級接口是GatewayFilterFactory,我們可以直接繼承它的兩個抽象類來簡化開發AbstractGatewayFilterFactory和AbstractNameValueGatewayFilterFactory,這兩個抽象類的區別就是前者接收一個參數(像StripPrefix和我們創建的這種),后者接收兩個參數(像AddResponseHeader)。
過濾器工廠的頂級接口是GatewayFilterFactory,有2個兩個較接近具體實現的抽象類,分別為AbstractGatewayFilterFactory和AbstractNameValueGatewayFilterFactory,這2個類前者接收一個參數,比如它的實現類RedirectToGatewayFilterFactory;后者接收2個參數,比如它的實現類AddRequestHeaderGatewayFilterFactory類。
可以參考gateway內置的Filter例如RedirectToGatewayFilterFactory的寫法,
- extends AbstractGatewayFilterFactory類,實現apply方法;
- 需要在工程的啟動文件Application類中,向Srping Ioc容器注冊RequestTimeGatewayFilterFactory類的Bean;
- 配置文件中配置,配置時只需要填寫xxxGatewayFilterFactory前面的xxx;或者通過編碼方式:例如:
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) { return builder.routes() .route(r -> r.path("/serviceApi/**").filters(f -> f.filter(new MonitoringGatewayFilter())) .uri("lb://tag")) .route(r -> r.path("/offline/**").filters(f -> f.filter(new MonitoringGatewayFilter())) .uri("lb://claimplat-offline")) .route(r -> r.path("/test/**").filters(f -> f.filter(new MonitoringGatewayFilter())) .uri("lb://claimplat-offline")) .route(r -> r.order(11000).path("/baidu") .filters(f -> f.addRequestHeader("x-request-uuid", UUID.randomUUID().toString()) .filter(new MonitoringGatewayFilter())) .uri("https://www.baidu.com")) .build(); }
三、Global Filter
GlobalFilter : 全局過濾器,不需要在配置文件中配置,作用在所有的路由上,最終通過GatewayFilterAdapter包裝成GatewayFilterChain可識別的過濾器,它為請求業務以及路由的URI轉換為真實業務服務的請求地址的核心過濾器,不需要配置,系統初始化時加載,並作用在每個路由上。
3.1、gateway內置的Global Filter
Spring Cloud Gateway框架內置的GlobalFilter如下:
3.2、自定義Global Filter
一般情況下GlobalFilter
全局過濾器是程序員使用較多的過濾器;可以用來自定義一些黑名單校驗、Token校驗等。
步驟:
- implements GlobalFilter, Ordered,實現filter方法;
- 需要在工程的啟動文件Application類中,向Srping Ioc容器注冊GlobalFilter類的Bean;
原文鏈接:https://blog.csdn.net/weixin_39693437/article/details/113318568
原文鏈接:https://blog.csdn.net/weixin_38361347/article/details/114108368