路由过滤器允许以某种方式对Http的请求(request)和响应(response)进行修改。对于特定的路由可以配置相应的路由过滤器。Spring Cloud Gateway中也内置了一些GatewayFilter工厂类。
注意,更多路由过滤器的详细使用,可以参考单元测试: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过滤器工厂的实现类是AddRequestHeaderGatewayFilterFactory,它使用两个参数,一个是name,一个是value。在application.yml中的配置如下所示:
spring:
cloud:
gateway:
routes:
- id: add_request_header_route
uri: http://www.xinyues.com
filters: - AddRequestHeader=X-Request-Foo, Bar
这个过滤器将会在下行的请求包头中添加键值对,也可以配合路由断言一起使用,给所有断言匹配的下行请求包头中添加此键值对。为了方便测试,在源码项目中使用了另外一种路由方式:根据服务名路由。如下面配置所示:
spring:
cloud:
gateway:
routes:
- id: app-a-route # 根据服务名路由
uri: lb://app-a #配置服务id
predicates:
- name: Path
args:
pattern: /app-a/** # 匹配的路径
filters:
- name: RewritePath
args:
regexp: /app-a/(?.*)
replacement: /${remaining}
- name: AddRequestHeader
args:
name: X-Request-Foo
value: Bar
可以看到,配置1与配置2中的filters的配置方式不一样,这是因为配置1只有一个过滤器,而配置2有多个过滤器,如果有多个过滤器,必须按对象定义的格式配置,如果只有一个过滤器可以使用配置1的方式,简化配置。
这时,启动源码(https://gitee.com/wgslucky/SpringCloud)中的如果请求的spring-cloud-gateway项目和spring-cloud-app-a项目,在浏览器输入请求地址:http://localhost:8080/app-a/app/index,可以看到在spring-cloud-app-a的控制台输了从包头中获取的X-Request-Foo的值Bar。
5.2 AddRequestParameter GatewayFilter Factory
AddRequestParameter的过滤器工厂的实现类是AddRequestParameterGatewayFilterFactory,它有两个参数,一个是name,一个是value,如下面的配置:
spring:
cloud:
gateway:
routes:
- id: app-a-route # 根据服务名路由
uri: lb://app-a #配置服务id
predicates:
- name: Path
args:
pattern: /app-a/** # 匹配的路径
filters:
- name: RewritePath
args:
regexp: /app-a/(?.*)
replacement: /${remaining}
- name: AddRequestHeader
args:
name: X-Request-Foo
value: Bar
- name: AddRequestParameter
args:
name: foo
value: bar
这个过滤器,可以给所有匹配的路径添加字符串类型的查询参数。
这时,启动源码中的如果请求的spring-cloud-gateway项目和spring-cloud-app-a项目,在浏览器输入请求地址:http://localhost:8080/app-a/app/add-request-parameter,可以看到日志输出了过滤器中添加的参数
5.3 AddResponseHeader GatewayFilter Factory
AddResponseHeader过滤器工厂的实现类是AddResponseHeaderGatewayFilterFactory,它有两个参数,一个是name,一个是value,而且都不能为空,在application.yml中的配置如下所示:
spring:
cloud:
gateway:
routes:
- id: app-a-route # 根据服务名路由
uri: lb://app-a #配置服务id
predicates: - name: Path
args:
pattern: /app-a/** # 匹配的路径
filters:
- name: RewritePath
args:
regexp: /app-a/(?.*)
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
这时,启动源码中的如果请求的spring-cloud-gateway项目和spring-cloud-app-a项目,在浏览器输入请求地址:http://localhost:8080/app-a/app/add-request-parameter,在谷歌浏览器中按F12,刷新请求,可以看到响应的Header里面包括了过滤器添加的值。
5.4 Hystrix GatewayFilter Factory
Hystrix过滤器工厂的实现类是HystrixGatewayFilterFactory。Hystrix是Netflix的一个库,它实现了circuit breaker pattern。使用Hystrix过滤器,可以向网关引入熔断器,保护网关后面的服务不会因为大流量而失去服务能力。当出现大流量处理不过来的时候,可以向使用Hystrix过滤器提供一个失败的响应,当下行失败事件产生时,就会给客户端直接返回失败响应信息。
为了使用Hystrix GatewayFilters,需要在项目中添加Hystrix的库依赖,如下面所示:
org.springframework.cloud
spring-cloud-starter-netflix-hystrix
Hystrix GatewayFilters需要一个name参数,它配置的就是HystrixCommand的名字。在application.yml中配置如下所示:
spring:
cloud:
gateway:
routes:
- id: hystrix_route
uri: http://example.org
filters: - Hystrix=myCommandName
这里fitlers中配置的就是一个名字为myCommandName的HystrixCommand。Hystrix Filters也可以配置一个fallbackUri参数,但是目前,只支持请求的forward:跳转。如果发生了失败,这个请求将会自动跳转到配置的controller中匹配到fallbackUri中。如下面配置所示:
spring:
cloud:
gateway:
routes:
- id: app-a-route # 根据服务名路由
uri: lb://app-a #配置服务id
predicates: - name: Path
args:
pattern: /app-a/** # 匹配的路径
filters:
- name: Hystrix
args:
name: fallbackcmd #熔断的名字,可以随便命名
fallbackUri: forward:/fallback # 如果触发了熔断,自动跳转到这个URI里面,在任务一个controller里面有这个URI即可。
当Hystrix的fallback被触发时,请求会自动转发到/fallback的URI里面,此URI在Spring Cloud Gateway项目中的定义如下面代码所示:
@RestController
@RequestMapping("/") public class FallbackController { //添加一个Controller方法,用于接收Hystrix失败时的fallback跳转。
@RequestMapping(value = "/fallback")
@ResponseStatus public Mono
从上面的案例中可以看到,fallbackUri跳转的是Spring Cloud Gateway项目内部的controller或handler,但是有时候也需要跳转到其它的服务中的controller或handler里面。如下面配置所示:
spring:
cloud:
gateway:
routes:
- id: app-a-route # 根据服务名路由
uri: lb://app-a #配置服务id
predicates:
- name: Path
args:
pattern: /app-a/** # 匹配的路径
filters:
- name: Hystrix
args:
name: fallbackcmd #熔断的名字,可以随便命名
fallbackUri: forward:/fallback # 如果触发了熔断,自动跳转到这个URI里面,在任务一个controller里面有这个URI即可。
- id: app-a-route-fallback
uri: lb://app-b
predicates:
- Path=/fallback
filters:
- name: RewritePath
args:
regexp: /fallback
replacement: /app/fallback
在源码中,如果启动动网关服务和spring-clouad-app-b服务,不启动spring-cloud-app-a服务,在浏览器中请求:http://localhost:8080/app-a/app/add-request-parameter,可以看到返回的内容是spring-cloud-app-b中AppController的fallback方法中返回的内容。
Hystrix的参数可以配置成全局默认值,也可以基本应用程序的属性配置,详细的可以参考Hystrix Wiki : https://github.com/Netflix/Hystrix/wiki/Configuration,比如配置上面例子中的fallbackcmd的超时时间为15秒,如下配置所示:
hystrix:
command:
fallbackcmd:
execution:
isolation:
thread:
timeoutInMilliseconds: 15000
5.5 FallbackHeaders GatewayFilter Factory
FallbackHeaders过滤器工厂的实现类是FallbackHeadersGatewayFilterFactory。当Hytrix触发fallback调用并且fallbackUri跳转的是另外一个服务的地址时,这个过滤器可以向跳转请求的Header中添加失败的详细信息。如下面的配置所示:
spring:
cloud:
gateway:
routes:
- id: app-a-route # 根据服务名路由
uri: lb://app-a #配置服务id
predicates:
- name: Path
args:
pattern: /app-a/** # 匹配的路径
filters:
- name: Hystrix
args:
name: fallbackcmd #熔断的名字,可以随便命名
fallbackUri: forward:/fallback # 如果触发了熔断,自动跳转到这个URI里面,在任务一个controller里面有这个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
在源码中,启动网关和spring-cloud-app-b服务,然后请求http://localhost:8080/app-a/app/add-request-parameter可以看到网页输了所有header中的信息,其它就是上面定义的test-header(只不过全部小写了)。如果想获取更多详细的信息,可以在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