Spring Cloud Gateway內(nèi)置GatewayFilter工廠類 (一)

路由過(guò)濾器允許以某種方式對(duì)Http的請(qǐng)求(request)和響應(yīng)(response)進(jìn)行修改签舞。對(duì)于特定的路由可以配置相應(yīng)的路由過(guò)濾器歉铝。Spring Cloud Gateway中也內(nèi)置了一些GatewayFilter工廠類。

注意搀罢,更多路由過(guò)濾器的詳細(xì)使用,可以參考單元測(cè)試:https://github.com/spring-cloud/spring-cloud-gateway/tree/master/spring-cloud-gateway-core/src/test/java/org/springframework/cloud/gateway/filter/factory

5.1 AddRequestHeaderGatewayFilter Factory

AddRequestHeader過(guò)濾器工廠的實(shí)現(xiàn)類是AddRequestHeaderGatewayFilterFactory赤拒,它使用兩個(gè)參數(shù),一個(gè)是name诱鞠,一個(gè)是value挎挖。在application.yml中的配置如下所示:

spring:
  cloud:
    gateway:
      routes: 
         - id: add_request_header_route
           uri: http://www.xinyues.com
           filters: - AddRequestHeader=X-Request-Foo, Bar

這個(gè)過(guò)濾器將會(huì)在下行的請(qǐng)求包頭中添加鍵值對(duì),也可以配合路由斷言一起使用航夺,給所有斷言匹配的下行請(qǐng)求包頭中添加此鍵值對(duì)蕉朵。為了方便測(cè)試,在源碼項(xiàng)目中使用了另外一種路由方式:根據(jù)服務(wù)名路由阳掐。如下面配置所示:

spring:
  cloud:
    gateway:
      routes: 
        - id: app-a-route     # 根據(jù)服務(wù)名路由
          uri: lb://app-a   #配置服務(wù)id
         predicates: 
        - name: Path
          args:
            pattern: /app-a/** # 匹配的路徑
        filters:
        - name: RewritePath
          args:
            regexp: /app-a/(?<remaining>.*)
            replacement: /${remaining}
        - name: AddRequestHeader
          args:
            name: X-Request-Foo
            value: Bar

可以看到墓造,配置1與配置2中的filters的配置方式不一樣,這是因?yàn)榕渲?只有一個(gè)過(guò)濾器锚烦,而配置2有多個(gè)過(guò)濾器,如果有多個(gè)過(guò)濾器帝雇,必須按對(duì)象定義的格式配置涮俄,如果只有一個(gè)過(guò)濾器可以使用配置1的方式,簡(jiǎn)化配置尸闸。

這時(shí)彻亲,啟動(dòng)源碼(https://gitee.com/wgslucky/SpringCloud)中的如果請(qǐng)求的spring-cloud-gateway項(xiàng)目和spring-cloud-app-a項(xiàng)目孕锄,在瀏覽器輸入請(qǐng)求地址:http://localhost:8080/app-a/app/index,可以看到在spring-cloud-app-a的控制臺(tái)輸了從包頭中獲取的X-Request-Foo的值Bar苞尝。

5.2 AddRequestParameter GatewayFilter Factory

AddRequestParameter的過(guò)濾器工廠的實(shí)現(xiàn)類是AddRequestParameterGatewayFilterFactory畸肆,它有兩個(gè)參數(shù),一個(gè)是name宙址,一個(gè)是value轴脐,如下面的配置:

spring:
  cloud:
    gateway:
      routes: 
       - id: app-a-route     # 根據(jù)服務(wù)名路由
        uri: lb://app-a   #配置服務(wù)id
       predicates: 
        - name: Path
          args:
            pattern: /app-a/** # 匹配的路徑
        filters:
        - name: RewritePath
          args:
            regexp: /app-a/(?<remaining>.*)
            replacement: /${remaining}
        - name: AddRequestHeader
          args:
            name: X-Request-Foo
        value: Bar
        - name: AddRequestParameter
          args: 
            name: foo
            value: bar

這個(gè)過(guò)濾器,可以給所有匹配的路徑添加字符串類型的查詢參數(shù)抡砂。

這時(shí)大咱,啟動(dòng)源碼中的如果請(qǐng)求的spring-cloud-gateway項(xiàng)目和spring-cloud-app-a項(xiàng)目,在瀏覽器輸入請(qǐng)求地址:http://localhost:8080/app-a/app/add-request-parameter注益,可以看到日志輸出了過(guò)濾器中添加的參數(shù)

5.3 AddResponseHeader GatewayFilter Factory

AddResponseHeader過(guò)濾器工廠的實(shí)現(xiàn)類是AddResponseHeaderGatewayFilterFactory碴巾,它有兩個(gè)參數(shù),一個(gè)是name丑搔,一個(gè)是value厦瓢,而且都不能為空,在application.yml中的配置如下所示:

spring:
  cloud:
    gateway:
      routes: 
      - id: app-a-route     # 根據(jù)服務(wù)名路由
        uri: lb://app-a   #配置服務(wù)id
       predicates: - name: Path
          args:
            pattern: /app-a/** # 匹配的路徑
        filters:
        - name: RewritePath
          args:
            regexp: /app-a/(?<remaining>.*)
            replacement: /${remaining}
        - name: AddRequestHeader
          args:
            name: X-Request-Foo
        value: Bar
        - name: AddRequestParameter
          args: 
            name: foo
        value: bar
        - name: AddResponseHeader
          args:
            name: foo
            value: bar2

這時(shí)啤月,啟動(dòng)源碼中的如果請(qǐng)求的spring-cloud-gateway項(xiàng)目和spring-cloud-app-a項(xiàng)目煮仇,在瀏覽器輸入請(qǐng)求地址:http://localhost:8080/app-a/app/add-request-parameter,在谷歌瀏覽器中按F12顽冶,刷新請(qǐng)求欺抗,可以看到響應(yīng)的Header里面包括了過(guò)濾器添加的值。

5.4 Hystrix GatewayFilter Factory

Hystrix過(guò)濾器工廠的實(shí)現(xiàn)類是HystrixGatewayFilterFactory强重。Hystrix是Netflix的一個(gè)庫(kù)绞呈,它實(shí)現(xiàn)了circuit breaker pattern。使用Hystrix過(guò)濾器间景,可以向網(wǎng)關(guān)引入熔斷器佃声,保護(hù)網(wǎng)關(guān)后面的服務(wù)不會(huì)因?yàn)榇罅髁慷シ?wù)能力。當(dāng)出現(xiàn)大流量處理不過(guò)來(lái)的時(shí)候倘要,可以向使用Hystrix過(guò)濾器提供一個(gè)失敗的響應(yīng)圾亏,當(dāng)下行失敗事件產(chǎn)生時(shí),就會(huì)給客戶端直接返回失敗響應(yīng)信息封拧。

為了使用Hystrix GatewayFilters志鹃,需要在項(xiàng)目中添加Hystrix的庫(kù)依賴,如下面所示:

   <dependency>
       <groupId>org.springframework.cloud</groupId>
        <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
    </dependency>

Hystrix GatewayFilters需要一個(gè)name參數(shù)泽西,它配置的就是HystrixCommand的名字曹铃。在application.yml中配置如下所示:

spring:
  cloud:
    gateway:
      routes: 
        - id: hystrix_route
        uri: http://example.org
        filters: - Hystrix=myCommandName

這里fitlers中配置的就是一個(gè)名字為myCommandName的HystrixCommand。Hystrix Filters也可以配置一個(gè)fallbackUri參數(shù)捧杉,但是目前陕见,只支持請(qǐng)求的forward:跳轉(zhuǎn)秘血。如果發(fā)生了失敗,這個(gè)請(qǐng)求將會(huì)自動(dòng)跳轉(zhuǎn)到配置的controller中匹配到fallbackUri中评甜。如下面配置所示:

spring:
  cloud:
    gateway:
      routes: 
       - id: app-a-route     # 根據(jù)服務(wù)名路由
        uri: lb://app-a   #配置服務(wù)id
        predicates: - name: Path
          args:
            pattern: /app-a/** # 匹配的路徑
        filters:
        - name: Hystrix
          args:
            name: fallbackcmd   #熔斷的名字灰粮,可以隨便命名
            fallbackUri: forward:/fallback   # 如果觸發(fā)了熔斷,自動(dòng)跳轉(zhuǎn)到這個(gè)URI里面忍坷,在任務(wù)一個(gè)controller里面有這個(gè)URI即可粘舟。

當(dāng)Hystrix的fallback被觸發(fā)時(shí),請(qǐng)求會(huì)自動(dòng)轉(zhuǎn)發(fā)到/fallback的URI里面承匣,此URI在Spring Cloud Gateway項(xiàng)目中的定義如下面代碼所示:

@RestController
@RequestMapping("/") public class FallbackController { //添加一個(gè)Controller方法蓖乘,用于接收Hystrix失敗時(shí)的fallback跳轉(zhuǎn)。
    @RequestMapping(value = "/fallback")
    @ResponseStatus public Mono<Map<String, Object>> fallback(ServerWebExchange exchange, Throwable throwable) {
        Map<String, Object> result = new HashMap<>(8);
        ServerHttpRequest request = exchange.getRequest();
        result.put("path", request.getPath().pathWithinApplication().value());
        result.put("method", request.getMethodValue()); if (null != throwable.getCause()) {
            result.put("message", throwable.getCause().getMessage());
        } else {
            result.put("message", throwable.getMessage());
        } return Mono.just(result);
    }
}

從上面的案例中可以看到韧骗,fallbackUri跳轉(zhuǎn)的是Spring Cloud Gateway項(xiàng)目?jī)?nèi)部的controller或handler嘉抒,但是有時(shí)候也需要跳轉(zhuǎn)到其它的服務(wù)中的controller或handler里面。如下面配置所示:

spring:
  cloud:
    gateway:
      routes: 
       - id: app-a-route     # 根據(jù)服務(wù)名路由
        uri: lb://app-a   #配置服務(wù)id
       predicates:
       - name: Path
          args:
            pattern: /app-a/** # 匹配的路徑
        filters:
        - name: Hystrix
          args:
            name: fallbackcmd   #熔斷的名字袍暴,可以隨便命名
            fallbackUri: forward:/fallback   # 如果觸發(fā)了熔斷些侍,自動(dòng)跳轉(zhuǎn)到這個(gè)URI里面,在任務(wù)一個(gè)controller里面有這個(gè)URI即可政模。
      - id: app-a-route-fallback
        uri: lb://app-b
        predicates:
        - Path=/fallback
        filters:
        - name: RewritePath
          args:
            regexp: /fallback
            replacement: /app/fallback

在源碼中岗宣,如果啟動(dòng)動(dòng)網(wǎng)關(guān)服務(wù)和spring-clouad-app-b服務(wù),不啟動(dòng)spring-cloud-app-a服務(wù)淋样,在瀏覽器中請(qǐng)求:http://localhost:8080/app-a/app/add-request-parameter耗式,可以看到返回的內(nèi)容是spring-cloud-app-b中AppController的fallback方法中返回的內(nèi)容。

Hystrix的參數(shù)可以配置成全局默認(rèn)值趁猴,也可以基本應(yīng)用程序的屬性配置刊咳,詳細(xì)的可以參考Hystrix Wiki : https://github.com/Netflix/Hystrix/wiki/Configuration,比如配置上面例子中的fallbackcmd的超時(shí)時(shí)間為15秒儡司,如下配置所示:

hystrix: 
  command:
    fallbackcmd:
        execution: 
            isolation:
              thread:
                timeoutInMilliseconds: 15000

5.5 FallbackHeaders GatewayFilter Factory

FallbackHeaders過(guò)濾器工廠的實(shí)現(xiàn)類是FallbackHeadersGatewayFilterFactory娱挨。當(dāng)Hytrix觸發(fā)fallback調(diào)用并且fallbackUri跳轉(zhuǎn)的是另外一個(gè)服務(wù)的地址時(shí),這個(gè)過(guò)濾器可以向跳轉(zhuǎn)請(qǐng)求的Header中添加失敗的詳細(xì)信息捕犬。如下面的配置所示:

spring:
  cloud:
    gateway:
      routes: 
      - id: app-a-route     # 根據(jù)服務(wù)名路由
        uri: lb://app-a   #配置服務(wù)id
        predicates: 
          - name: Path
          args:
            pattern: /app-a/** # 匹配的路徑
        filters:
        - name: Hystrix
          args:
            name: fallbackcmd   #熔斷的名字跷坝,可以隨便命名
            fallbackUri: forward:/fallback   # 如果觸發(fā)了熔斷,自動(dòng)跳轉(zhuǎn)到這個(gè)URI里面碉碉,在任務(wù)一個(gè)controller里面有這個(gè)URI即可柴钻。
      - id: app-a-route-fallback
        uri: lb://app-b
        predicates:
        - Path=/fallback
        filters:
        - name: RewritePath
          args:
            regexp: /fallback
            replacement: /app/fallback
        - name: FallbackHeaders
          args:
            executionExceptionTypeHeaderName: Test-Header

在源碼中,啟動(dòng)網(wǎng)關(guān)和spring-cloud-app-b服務(wù)垢粮,然后請(qǐng)求http://localhost:8080/app-a/app/add-request-parameter可以看到網(wǎng)頁(yè)輸了所有header中的信息顿颅,其它就是上面定義的test-header(只不過(guò)全部小寫了)。如果想獲取更多詳細(xì)的信息,可以在args中配置更多的字段粱腻,這些字段名在FallbackHeadersGatewayFilterFactory的Config類里面,如下面代碼所示:

 private String executionExceptionTypeHeaderName = EXECUTION_EXCEPTION_TYPE; 
 private String executionExceptionMessageHeaderName = EXECUTION_EXCEPTION_MESSAGE;
 private String rootCauseExceptionTypeHeaderName = ROOT_CAUSE_EXCEPTION_TYPE; 
 private String rootCauseExceptionMessageHeaderName = ROOT_CAUSE_EXCEPTION_MESSAGE;

源碼地址:https://gitee.com/wgslucky/SpringCloud QQ交流群:677464431

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末斩跌,一起剝皮案震驚了整個(gè)濱河市绍些,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌耀鸦,老刑警劉巖柬批,帶你破解...
    沈念sama閱讀 212,454評(píng)論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異袖订,居然都是意外死亡氮帐,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門洛姑,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)上沐,“玉大人,你說(shuō)我怎么就攤上這事楞艾〔瘟” “怎么了?”我有些...
    開封第一講書人閱讀 157,921評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵硫眯,是天一觀的道長(zhǎng)蕴侧。 經(jīng)常有香客問(wèn)我,道長(zhǎng)两入,這世上最難降的妖魔是什么净宵? 我笑而不...
    開封第一講書人閱讀 56,648評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮裹纳,結(jié)果婚禮上择葡,老公的妹妹穿的比我還像新娘。我一直安慰自己痊夭,他們只是感情好刁岸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,770評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著她我,像睡著了一般虹曙。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上番舆,一...
    開封第一講書人閱讀 49,950評(píng)論 1 291
  • 那天酝碳,我揣著相機(jī)與錄音,去河邊找鬼恨狈。 笑死疏哗,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的禾怠。 我是一名探鬼主播返奉,決...
    沈念sama閱讀 39,090評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼贝搁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了芽偏?” 一聲冷哼從身側(cè)響起雷逆,我...
    開封第一講書人閱讀 37,817評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎污尉,沒想到半個(gè)月后膀哲,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,275評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡被碗,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,592評(píng)論 2 327
  • 正文 我和宋清朗相戀三年某宪,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片锐朴。...
    茶點(diǎn)故事閱讀 38,724評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡兴喂,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出包颁,到底是詐尸還是另有隱情瞻想,我是刑警寧澤,帶...
    沈念sama閱讀 34,409評(píng)論 4 333
  • 正文 年R本政府宣布娩嚼,位于F島的核電站蘑险,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏岳悟。R本人自食惡果不足惜佃迄,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,052評(píng)論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望贵少。 院中可真熱鬧呵俏,春花似錦、人聲如沸滔灶。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)录平。三九已至麻车,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間斗这,已是汗流浹背动猬。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留表箭,地道東北人赁咙。 一個(gè)月前我還...
    沈念sama閱讀 46,503評(píng)論 2 361
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親彼水。 傳聞我的和親對(duì)象是個(gè)殘疾皇子崔拥,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,627評(píng)論 2 350

推薦閱讀更多精彩內(nèi)容