微服务当前这么火爆的程度,如果不能学会一种微服务框架技术。怎么能升职加薪,增加简历的筹码?spring cloud 和 Dubbo 需要单独学习。说没有时间?没有精力?要学俩个框架?而Spring Cloud alibaba只需要你学会一个就会拥有俩种微服务治理框架技术。何乐而不为呢?加油吧!骚猿年
上一篇我们讲述了gateway 的路由功能其实也类似与zuul服务的路由转发。
今天主要讲一下断言机制。
介绍 Spring Cloud Gateway将路由作为Spring WebFlux HandlerMapping基础架构的一部分进行匹配。Spring Cloud Gateway包括许多内置的Route Predicate工厂。所有这些断言都与HTTP请求的不同属性匹配。多个Route Predicate工厂可以合并,也可以通过逻辑合并
可以看到gateway 提供如此之多丰富的断言,方式。
具体使用还得参照业务场景来选择更适合我们的业务场景。
gateway 已经给我们提供了非常丰富的过滤器
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工厂采用名称和值参数。
spring: cloud: gateway: routes: - id: add_request_parameter_route uri: https://example.org filters: - AddRequestParameter=foo, bar
这将添加foo=bar到所有匹配请求的下游请求的查询字符串中。
AddRequestParameter知道用于匹配路径或主机的URI变量。URI变量可用于该值,并将在运行时扩展。
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: dedupe_response_header_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。
Hystrix过滤器还可以接受可选fallbackUri参数。当前,仅forward:支持计划的URI。如果调用了后备,则请求将被转发到与URI相匹配的控制器。
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负载平衡。
主要方案是对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.HYSTRIX_EXECUTION_EXCEPTION_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:
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参数和特定于速率限制器的参数。
全局过滤器和GatewayFilter的组合订购
因为spring cloud gateway 提供的内置过滤器太多了。不在这里一一介绍
可以查看官方的文档 进行了解学习
gateway官方文档
https://cloud.spring.io/spring-cloud-gateway/reference/html/
接下来讲一下,全局过滤器GlobalFilter接口。
可以看一下默认的实现的全局过滤器 ,除去AuthorizeFilter过滤器都是默认的过滤器
具体的里面的作用,其实上面的已经有了简单的描述不在复述。有兴趣的同学可以看看里面的实现,都是利用过滤器做转发或者一些对流量请求的修改、鉴权、等操作
1、pom引入spring-boot-starter-actuator 。因为之前就直接在parent pom 进行了引入操作。不再次引入
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency>
2、配置文件bootstrap.yml中开启监控管理端点
management: endpoints: web: exposure: include: "*" endpoint: health: show-details: ALWAYS
3、请求浏览器 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 网关服务 一
如何喜欢可以关注分享本公众号。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。转载请附带公众号二维码