路由過(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