Spring Cloud gateway 網關服務二 斷言、過濾器

微服務當前這麼火爆的程度,若是不能學會一種微服務框架技術。怎麼能升職加薪,增長簡歷的籌碼?spring cloud 和 Dubbo 須要單獨學習。說沒有時間?沒有精力?要學倆個框架?而Spring Cloud alibaba只須要你學會一個就會擁有倆種微服務治理框架技術。何樂而不爲呢?加油吧!騷猿年

上一篇咱們講述了gateway 的路由功能其實也相似與zuul服務的路由轉發。今天主要講一下斷言機制。html

內置的斷言工廠

介紹 Spring Cloud Gateway將路由做爲Spring WebFlux HandlerMapping基礎架構的一部分進行匹配。Spring Cloud Gateway包括許多內置的Route Predicate工廠。全部這些斷言都與HTTP請求的不一樣屬性匹配。多個Route Predicate工廠能夠合併,也能夠經過邏輯合併

file

能夠看到gateway 提供如此之多豐富的斷言,方式。react

  • 好比說時間控住的,咱們能想到秒殺場景。
  • ip 的咱們能想到金絲雀測試
  • 權重咱們可使用灰度等等場景的應用

具體使用還得參照業務場景來選擇更適合咱們的業務場景。git

gateway 過濾器 分爲全局過濾器,個性化過濾器

gateway 已經給咱們提供了很是豐富的過濾器github

  • AddRequestHeader GatewayFilter工廠採用名稱和值參數。
這會將X-Request-Foo:Bar標頭添加到全部匹配請求的下游請求的標頭中。複製代碼
spring:
            cloud:
                gateway:
                    routes:
                    - id: add_request_header_route
                        uri: https://example.org
                        filters:
                        - AddRequestHeader=X-Request-Foo, Bar複製代碼
AddRequestHeader知道用於匹配路徑或主機的URI變量。URI變量可用於該值,並將在運行時擴展。複製代碼
spring:
            cloud:
                gateway:
                    routes:
                    - id: add_request_header_route
                        uri: https://example.org
                        predicates:
                        - Path=/foo/{segment}
                        filters:
                        - AddRequestHeader=X-Request-Foo, Bar-{segment}複製代碼

-AddResponseHeader GatewayFilter工廠採用名稱和值參數。web

spring:
        cloud:
            gateway:
                routes:
                - id: add_request_parameter_route
                    uri: https://example.org
                    filters:
                    - AddRequestParameter=foo, bar複製代碼

這將添加foo=bar到全部匹配請求的下游請求的查詢字符串中。正則表達式

AddRequestParameter知道用於匹配路徑或主機的URI變量。URI變量可用於該值,並將在運行時擴展。redis

spring:
        cloud:
            gateway:
                routes:
                - id: add_request_parameter_route
                    uri: https://example.org
                    predicates:
                    - Host: {segment}.myhost.org
                    filters:
                    - AddRequestParameter=foo, bar-{segment}複製代碼
  • AddResponseHeader GatewayFilter工廠採用名稱和值參數。
spring:
            cloud:
                gateway:
                    routes:
                    - id: add_response_header_route
                        uri: https://example.org
                        filters:
                        - AddResponseHeader=X-Response-Foo, Bar複製代碼
這會將X-Response-Foo:Bar標頭添加到全部匹配請求的下游響應的標頭中。複製代碼
AddResponseHeader知道用於匹配路徑或主機的URI變量。URI變量可用於該值,並將在運行時擴展。
        spring:
            cloud:
                gateway:
                    routes:
                    - id: add_response_header_route
                        uri: https://example.org
                        predicates:
                        - Host: {segment}.myhost.org
                        filters:
                        - AddResponseHeader=foo, bar-{segment}複製代碼
  • DedupeResponseHeader GatewayFilter工廠採用一個name參數和一個可選strategy參數。name能夠包含標題名稱列表,以空格分隔。
    spring:
    cloud:
    gateway:
    routes:
    • id: deduperesponseheader_route
      uri: https://example.org
      filters:
      • DedupeResponseHeader=Access-Control-Allow-Credentials Access-Control-Allow-Origin
若是網關CORS邏輯和下游邏輯都添加了重複的值Access-Control-Allow-Credentials和Access-Control-Allow-Origin響應標頭,則這將刪除它們。複製代碼
DedupeResponseHeader過濾器還接受可選strategy參數。可接受的值爲RETAIN_FIRST(默認值)RETAIN_LAST,和RETAIN_UNIQUE
    複製代碼
  • Hystrix是Netflix的一個庫,用於實現斷路器模式。Hystrix GatewayFilter容許您將斷路器引入網關路由,保護您的服務免受級聯故障的影響,並容許您在下游故障的狀況下提供後備響應
    要在項目中啓用Hystrix GatewayFilters,請spring-cloud-starter-netflix-hystrix從Spring Cloud Netflix添加依賴項。
Hystrix GatewayFilter工廠須要一個name參數,它是的名稱HystrixCommand。
            spring:
                cloud:
                    gateway:
                        routes:
                        - id: hystrix_route
                            uri: https://example.org
                            filters:
                            - Hystrix=myCommandName
                            複製代碼

這會將其他的過濾器包裝在HystrixCommand帶有命令名的中myCommandName。spring

Hystrix過濾器還能夠接受可選fallbackUri參數。當前,僅forward:支持計劃的URI。若是調用了後備,則請求將被轉發到與URI相匹配的控制器。apache

spring:
            cloud:
                gateway:
                    routes:
                    - id: hystrix_route
                        uri: lb://backing-service:8088
                        predicates:
                        - Path=/consumingserviceendpoint
                        filters:
                        - name: Hystrix
                            args:
                                name: fallbackcmd
                                fallbackUri: forward:/incaseoffailureusethis
                        - RewritePath=/consumingserviceendpoint, /backingserviceendpoint
複製代碼

/incaseoffailureusethis調用Hystrix後備時,它將轉發到URI。請注意,此示例還經過lb目標URI 上的前綴演示了(可選)Spring Cloud Netflix Ribbon負載平衡。bootstrap

主要方案是對fallbackUri網關應用程序中的內部控制器或處理程序使用。可是,也能夠將請求從新路由到外部應用程序中的控制器或處理程序,以下所示:

spring:
            cloud:
                gateway:
                    routes:
                    - id: ingredients
                        uri: lb://ingredients
                        predicates:
                        - Path=//ingredients/**
                        filters:
                        - name: Hystrix
                            args:
                                name: fetchIngredients
                                fallbackUri: forward:/fallback
                    - id: ingredients-fallback
                        uri: http://localhost:9994
                        predicates:
                        - Path=/fallback複製代碼

在此示例中,fallback網關應用程序中沒有終結點或處理程序,可是另外一個應用程序中有一個終結點或處理程序,在下注冊localhost:9994。

若是將請求轉發給後備,則Hystrix網關過濾器還會提供Throwable引發請求的。它已ServerWebExchange做爲 ServerWebExchangeUtils.HYSTRIXEXECUTIONEXCEPTION_ATTR屬性添加到,能夠在網關應用程序中處理後備時使用。

對於外部控制器/處理程序方案,能夠添加帶有異常詳細信息的標頭。您能夠在FallbackHeaders GatewayFilter Factory部分中找到有關它的更多信息。

Hystrix設置(例如超時)可使用全局默認值配置,也可使用Hystrix Wiki上說明的應用程序屬性在逐條路由的基礎上進行配置。

要爲上述示例路由設置5秒超時,將使用如下配置:

hystrix.command.fallbackcmd.execution.isolation.thread.timeoutInMilliseconds: 5000
複製代碼
  • 該FallbackHeaders工廠可讓你在轉發到請求的頭部添加蝟執行異常的詳細信息fallbackUri在如下狀況下在外部應用程序
    spring:
    cloud:
    gateway:
    routes:
    • id: ingredients
      uri: lb://ingredients
      predicates:
      • Path=//ingredients/**
        filters:
      • name: Hystrix
        args:
        name: fetchIngredients
        fallbackUri: forward:/fallback
    • id: ingredients-fallback
      uri: http://localhost:9994
      predicates:
      • Path=/fallback
        filters:
      • name: FallbackHeaders
        args:
        executionExceptionTypeHeaderName: Test-Header
在此示例中,在運行時發生執行異常後HystrixCommand,該請求將轉發到在上fallback運行的應用中的端點或處理程序localhost:9994。具備異常類型,消息和-if available-根本緣由異常類型和消息的標頭將由FallbackHeaders過濾器添加到該請求。複製代碼

經過設置下面列出的參數的值及其默認值,能夠在配置中覆蓋標頭的名稱:

- executionExceptionTypeHeaderName("Execution-Exception-Type")複製代碼
- executionExceptionMessageHeaderName("Execution-Exception-Message")複製代碼
- rootCauseExceptionTypeHeaderName("Root-Cause-Exception-Type")複製代碼
- rootCauseExceptionMessageHeaderName("Root-Cause-Exception-Message")複製代碼

您能夠在Hystrix GatewayFilter Factory部分中找到有關Hystrix如何與Gateway一塊兒工做的更多信息。

  • MapRequestHeader GatewayFilter工廠採用'fromHeader'和'toHeader'參數。它建立一個新的命名標頭(toHeader),並從傳入的HTTP請求中從現有的命名標頭(fromHeader)中提取值。若是輸入標頭不存在,則過濾器不起做用。若是新的命名標頭已經存在,則其值將使用新值進行擴充。
spring:
            cloud:
                gateway:
                    routes:
                    - id: map_request_header_route
                        uri: https://example.org
                        filters:
                        - MapRequestHeader=Bar, X-Request-Foo複製代碼

這會將X-Request-Foo: 標頭添加到下游請求的標頭中,其中包含來自傳入的HTTP請求Bar標頭的更新值。

  • PrefixPath GatewayFilter工廠採用單個prefix參數。
    spring:
    cloud:
    gateway:
    routes:
    • id: prefixpath_route
      uri: https://example.org
      filters:
      • PrefixPath=/mypath

這將/mypath做爲全部匹配請求的路徑的前綴。所以,對的請求/hello將發送給/mypath/hello。

  • PreserveHostHeader GatewayFilter工廠沒有參數。此過濾器設置請求屬性,路由過濾器將檢查該請求屬性,以肯定是否應發送原始主機頭,而不是由HTTP客戶端肯定的主機頭。
spring:
            cloud:
                gateway:
                    routes:
                    - id: preserve_host_route
                        uri: https://example.org
                        filters:
                        - PreserveHostHeader
- RequestRateLimiter GatewayFilter Factory使用一種RateLimiter實現來肯定是否容許繼續當前請求。若是不是,HTTP 429 - Too Many Requests則返回狀態(默認)。此過濾器採用一個可選keyResolver參數和特定於速率限制器的參數。複製代碼
  • Redis RateLimiter GatewayFilter工廠 redis實現基於Stripe所作的工做。它須要使用spring-boot-starter-data-redis-reactiveSpring Boot啓動器。
  • RedirectTo GatewayFilter工廠採用status和url參數。狀態應該是300系列重定向http代碼,例如301。URL應該是有效的URL。這將是Location標題的值
  • RemoveHopByHopHeadersFilter GatewayFilter工廠從轉發的請求中刪除標頭。被刪除的頭的默認列表來自IETF。
  • RemoveRequestHeader GatewayFilter工廠採用一個name參數。它是要刪除的標題的名稱。
  • RemoveResponseHeader GatewayFilter工廠採用一個name參數。它是要刪除的標題的名稱。
  • RemoveRequestParameter GatewayFilter工廠採用一個name參數。它是要刪除的查詢參數的名稱。
  • RewritePath GatewayFilter工廠採用路徑regexp參數和replacement參數。這使用Java正則表達式提供了一種靈活的方式來重寫請求路徑。
  • RewriteLocationResponseHeader GatewayFilter工廠Location一般會修改響應標頭的值,以擺脫後端特定的詳細信息。這須要stripVersionMode,locationHeaderName,hostValue,和protocolsRegex參數。
  • 該RewriteResponseHeader GatewayFilter廠須要name,regexp和replacement參數。它使用Java正則表達式以靈活的方式重寫響應標頭值。
  • SaveSession GatewayFilter Factory 在向下遊轉發呼叫以前強制執行WebSession::save操做。這在將Spring Session之類的東西與惰性數據存儲一塊兒使用時特別有用,而且須要確保在進行轉發呼叫以前已保存會話狀態。
  • SetPath GatewayFilter工廠採用路徑template參數。經過容許路徑的模板段,它提供了一種操做請求路徑的簡單方法。這使用了Spring Framework中的uri模板。容許多個匹配段。
  • SetRequestHeader GatewayFilter工廠採用name和value參數。
  • SetResponseHeader GatewayFilter工廠採用name和value參數
  • SetStatus GatewayFilter工廠採用單個status參數。它必須是有效的Spring HttpStatus。它能夠是整數值404或枚舉的字符串表示形式NOT_FOUND
  • StripPrefix GatewayFilter工廠採用一個參數parts。該parts參數指示在向下遊發送請求以前,要從請求中剝離的路徑中的零件數
  • 重試GatewayFilter工廠
  • RequestSize GatewayFilter工廠 當請求大小大於容許的限制時,RequestSize GatewayFilter Factory能夠限制請求到達下游服務。過濾器將RequestSize參數做爲請求的容許大小限制(以字節爲單位
  • 修改請求正文GatewayFilter工廠 該過濾器被認爲是BETA,API未來可能會更改 此過濾器可用於在網關將請求主體發送到下游以前修改請求主體。
  • 默認過濾器 若是您想添加過濾器並將其應用於全部路由,則可使用spring.cloud.gateway.default-filters。該屬性採用過濾器列表
  • 全局過濾器 該GlobalFilter接口具備與相同的簽名GatewayFilter。這些是特殊過濾器,有條件地應用於全部路由。(此界面和用法可能會在未來的里程碑中更改)。
  • 全局過濾器和GatewayFilter的組合訂購

由於spring cloud gateway 提供的內置過濾器太多了。不在這裏一一介紹能夠查看官方的文檔 進行了解學習

gateway官方文檔

https://cloud.spring.io/spring-cloud-gateway/reference/html/

接下來說一下,全局過濾器GlobalFilter接口。

  • GlobalFilter 和 GatewayFilter 的 #filter(ServerWebExchange, GatewayFilterChain) 方法簽名一致;
  • GlobalFilter會做用於全部的路由上;
  • 在將來的里程碑版本中可能做一些調整;

能夠看一下默認的實現的全局過濾器 ,除去AuthorizeFilter過濾器都是默認的過濾器

file

具體的裏面的做用,其實上面的已經有了簡單的描述不在複述。有興趣的同窗能夠看看裏面的實現,都是利用過濾器作轉發或者一些對流量請求的修改、鑑權、等操做

能夠經過actuator 模塊監控查詢 GlobalFilter實現類

一、pom引入spring-boot-starter-actuator 。由於以前就直接在parent pom 進行了引入操做。再也不次引入

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-actuator</artifactId>
</dependency>複製代碼

二、配置文件bootstrap.yml中開啓監控管理端點

management:
  endpoints:
    web:
      exposure:
        include: "*"
  endpoint:
    health:
      show-details: ALWAYS複製代碼

三、請求瀏覽器 http://localhost:9000/actuator/gateway/globalfilters

{
org.springframework.cloud.gateway.filter.AdaptCachedBodyGlobalFilter@4b957db0: -2147482648,
org.springframework.cloud.gateway.filter.WebsocketRoutingFilter@273fa9e: 2147483646,
com.xian.cloud.filter.AuthorizeFilter@4b03cbad: 0,
org.springframework.cloud.gateway.filter.ForwardRoutingFilter@8840c98: 2147483647,
org.springframework.cloud.gateway.filter.NettyRoutingFilter@5c313224: 2147483647,
org.springframework.cloud.gateway.filter.NettyWriteResponseFilter@1e1e837d: -1,
org.springframework.cloud.gateway.filter.RouteToRequestUrlFilter@5d71b500: 10000,
org.springframework.cloud.gateway.filter.LoadBalancerClientFilter@5b29ab61: 10100,
org.springframework.cloud.gateway.filter.GatewayMetricsFilter@527a8665: -2147473648,
org.springframework.cloud.gateway.filter.ForwardPathFilter@626b639e: 0
}複製代碼

觀察這些實現類。都是實現 GlobalFilter、Ordered倆個接口實現本身的全局過濾器

建立 AuthorizeFilter

package com.xian.cloud.filter;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * <Description>
 *
 * @author xianliru@100tal.com
 * @version 1.0
 * @createDate 2019/11/04 18:06
 */
@Component
@Slf4j
public class AuthorizeFilter implements GlobalFilter, Ordered {


    private static final String AUTHORIZE_TOKEN = "Authorization";
    private static final String AUTHORIZE_UID = "uid";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {

        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();

        ServerHttpRequest.Builder mutate = request.mutate();

        String token = headers.getFirst( AUTHORIZE_TOKEN );
        String uid = headers.getFirst( AUTHORIZE_UID );
        String method = request.getMethodValue();

        log.info( "AuthorizeFilter token 全局過濾器 token:{},uid:{}",token,uid );
        if (token == null) {
            token = request.getQueryParams().getFirst( AUTHORIZE_TOKEN );
        }
        if(StringUtils.isNotBlank(token)){
                        //TODO 權限驗證
        }

        return chain.filter( exchange );
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
複製代碼

而後啓動服務。

curl http://localhost:9000/client/client/test日誌打印

[2019-11-05 19:30:52.802] [INFO ] com.xian.cloud.filter.AuthorizeFilter - AuthorizeFilter token 全局過濾器 token:null,uid:null複製代碼

下一篇咱們將介紹定製的過濾器,針對下游服務對應過濾器

摘自參考 spring cloud 官方文檔

示例代碼地址

服務器nacos 地址 http://47.99.209.72:8848/nacos

往期地址 spring cloud alibaba 地址

spring cloud alibaba 簡介

Spring Cloud Alibaba (nacos 註冊中心搭建)

Spring Cloud Alibaba 使用nacos 註冊中心

Spring Cloud Alibaba nacos 配置中心使用

spring cloud 網關服務

Spring Cloud zuul網關服務 一

Spring Cloud 網關服務 zuul 二

Spring Cloud 網關服務 zuul 三 動態路由

Spring Cloud alibaba網關 sentinel zuul 四 限流熔斷

Spring Cloud gateway 網關服務 一

如何喜歡能夠關注分享本公衆號。file

相關文章
相關標籤/搜索