目录
AddRequestParameter GatewayFilter Factory
AddResponseHeader GatewayFilter Factory
RequestRateLimiter GatewayFilter Factory
六、Spring Cloud Gateway集成Nacos实现请求负载
七、Spring Cloud Gateway集成Sentinel网关限流原理
一、API网关的作用
在API网关层可以把后端的多个服务进行整合,然后提供唯一的业务接口,客户端只需要调用这个接口即可完成数据的获取及展示。在网关中会再消费后端的多个微服务,进行统一的整合,给客户端返回唯一的响应。网关不仅只做请求的转发和服务的整合,有了网关这个统一的入口之后,它还能提供以下功能:
- 针对所有请求进行统一鉴权、限流、熔断、日志
- 协议转化。针对后端多种不同的协议,在网关层统一处理后以HTTP对外提供服务
- 统一错误码处理
- 请求转发,并且可以基于网站实现内、外网隔离
1.统一认证鉴权
统一认证鉴权包含如下两个部分:
- 客户端身份认证:主要用于判断当前用户是否为合法用户,一般的做法是使用账号和密码进行验证。当然,对于一些复杂的认证场景会采用加密算法来实现,比如公、私钥
- 访问权限控制:身份认证和访问权限一般是相互联系的,当身份认证通过后,就需要判断该用户是否有权限访问该资源,或者该用户的访问权限是否被限制了
网关层面处理办法:增加API网关后,在网关层进行请求拦截,获取请求中附带的用户身份信息,调用统一认证中心对请求进行身份认证,在确认身份之后再检查是否有资源的访问权限
2.灰度发布
所谓灰度发布,就是将要发布的功能先开放给一小部分用户使用,把影响控制在一个非常小的范围,比如A/B Test就是一种灰度发布方式,即一部分用户继续使用A功能,另外一小部分用户使用新的B功能。通过对B功能的满意度调查,逐渐放大B功能的投放,直到全量或者回滚该版本
网关层面处理方法:网关是所有客户请求的入口,因此在网关层可以通过灰度规则控制部分流量的路由,从而实现灰度发布。网关对请求进行拦截之后,会根据分流引擎配置的分流规则进行请求的路由
二、Spring Cloud Gateway网关实战
- 首先准备两个Spring Boot应用:1.spring-cloud-gateway-service(模拟一个微服务);2.spring-cloud-gateway-sample(独立的网关服务)
- spring-cloud-gateway-service,基于Spring Boot构建一个应用,添加spring-boot-starter-web依赖,创建一个业务响应类发布一个接口并启动
- spring-cloud-gateway-sample,创建Spring Boot应用,添加spring-cloud-starter-gateway依赖;在application.yml文件中添加Gateway的路由配置
spring:
cloud:
gateway:
routes:
- predicates:
- Path=/gateway/** (匹配路径)
filters:
- StripPrefix=1 (跳过前缀)
uri: http://localhost:8080/say (spring-cloud-gateway-service的访问地址)
server:
port:8088
注释:上述配置中字段的含义说明如下:
id:自定义路由ID,保持唯一
uri:目标服务地址,支持普通URI及lb://应用注册服务名称,后者表示从注册中心获取集群服务地址
predicates:路由条件,根据匹配的结果决定是否执行该请求路由
filters:过滤规则,包含pre和post过滤。其中StripPrefix=1,表示Gateway根据该配置的值去掉URL路径中的部分前缀
- 启动应用,验证结果
三、Spring Cloud Gateway原理分析
Spring Cloud Gateway的请求处理过程中有几个非常重要的概念,如下:
- 路由(Route):它是网关的基本组件,由ID、目标URI、Predicate集合、Filter集合组成
- 谓语(Predicate):它是java8引入的函数式接口,提供了断言的功能。它可以匹配HTTP请求中的任何内容。如果Predicate的聚合判断结果为true,则意味着该请求会被当前Router进行转发
- 过滤器(Filter):为请求提供前置和后置的过滤
原理:Spring Cloud Gateway启动时基于Netty Server监听一个指定的端口。当客户端发送一个请求到网关时,网关会根据一系列Predicate的匹配结果来决定访问哪个Route路由,然后根据过滤器链进行请求的处理。也就是首先执行pre过滤器链,然后将请求发送到后端,最后执行Post过滤器链
四、Predicate
谓语,它允许接收一个参数并返回一个布尔值,可以用于条件过滤、请求参数的校验。在Spring Cloud Gateway中,Predicate提供了路由规则的匹配机制,比如:spring.cloud.gateway.routers[0].predicates[0]=Path=/gateway/**,意思是通过Path属性来匹配URL前缀是/gateway/的请求
1.指定时间规则匹配路由
根据配置的时间来匹配路由规则,包含以下三种:
- 请求在指定日期之前,对应BeforeRoutePredicateFactory
- 请求在指定日期之后,对应AfterRoutePredicateFatory
- 请求在指定的两个日期之间,对应BetweenRoutePredicateFactory
举例:我们希望在2020年6月1号之前发生的请求都路由到www.example.com,配置如下
spring:
cloud:
gateway:
routes:
- id:before_route
uri:http://www.example.com
predicates:
- After:2020-06-01T24:00:00.000+08:00[Asia/Shanghai]
注意:配置的日期时间必须满足ZonedDateTime
2.Cookie匹配路由
Cookie Route Predicate Factory规则,判断请求中携带的Cookie是否匹配配置的规则
举例:要求请求需要携带一个name=chocolate,并且value需要通过正则表达式匹配mic,才能路由到http://example.com,配置如下:
spring:
cloud:
gateway:
routes:
- id:cookie_route
uri:http://www.example.com
predicates:
- Cookie=chocolate, mic
3.Header匹配路由
Header Route Predicate Factory规则,判断请求中Header头消息对应的name和value与Predicate配置的值是否匹配,value也是正则匹配形式
举例:匹配请求中Header头中的name=X-Request-Id,并且value会根据正则表达式匹配\d+,也就是匹配1个以上的数字,配置如下:
spring:
cloud:
gateway:
routes:
- id:header_route
uri:http://www.example.com
predicates:
- Header=X-Request-Id, \d+
4.Host匹配路由
HTTP请求会携带一个Host字段,这个字段表示请求的服务器网址。Host Route Predicate Factory规则就是匹配请求中的Host字段机进行路由
举例:Host可以配置一个列表,列表中的每个元素通过,分割。当前请求中Host的值符合**.somehost.com,**anotherhost.com时,才会将请求路由到http://example.com,配置如下:
spring:
cloud:
gateway:
routes:
- id:host_route
uri:http://www.example.com
predicates:
- Host=**.somehost.com,**anotherhost.com
5.请求方法匹配路由
Method Route Predicate Factory规则会根据HTTP请求的Method属性来匹配以实现路由
举例:如果HTTP请求的方法是GET或POST,都会路由到http://example/com,配置如下:
spring:
cloud:
gateway:
routes:
- id:method_route
uri:http://www.example.com
predicates:
- Method=GET,POST
6.请求路径匹配路由
${segment}是一种比较特殊的占位符,/*表示单层路径匹配,/**表示多层路径匹配
举例:匹配请求的URI为/red/*、/blue/*时,才会转发到http://example.com,配置如下:
spring:
cloud:
gateway:
routes:
- id:path_route
uri:http://www.example.com
predicates:
- Path=/red/{segment},/blue/{segment}
五、Filter
1.定义
Filter分为Pre类型的过滤器和Post类型的过滤器:
- Pre类型的过滤器在请求转发到服务端之前执行,在Pre类型过滤器链中可以做鉴权、限流等操作
- Post类型的过滤器在请求执行完成之后、将结果返回给客户端之前执行
在Spring Cloud Gateway中内置了很多Filter,Filter有两种实现:分别是GatewayFilter和GlobalFilter。GlobalFilter会应用到所有的路由上;而GatewayFilter只会应用到单个路由或者一个分组的路由上
2.GatewayFilter
AddRequestParameter GatewayFilter Factory
该过滤器的功能是对所有匹配的请求添加一个查询参数,举例:
spring:
cloud:
gateway:
routes:
- id:add_request_parameter_route
uri:http://example.com
filters:
- AddRequestParamter=foo,bar
注:上面这段配置,会对所有请求增加foo=bar这个参数
AddResponseHeader GatewayFilter Factory
该过滤器会对所有匹配的请求,在返回结果给客户端之前,在Header中添加相应的数据,举例:
spring:
cloud:
gateway:
routes:
- id:add_request_header_route
uri:http://example.com
filters:
- AddResponseHeader=X-Response-Foo,Bar
注:上面这段配置,会在Response中添加Header头,key=X-Response-Foo,value=Bar
RequestRateLimiter GatewayFilter Factory
该过滤器会对访问到当前网关的所有请求执行限流过滤,如果被限流,默认情况下会响应HTTP 429-Too Many Requests。它默认提供了RedisRateLimiter的限流实现,它采用令牌桶算法实现限流功能
spring:
cloud:
gateway:
routes:
- id:requestratelimiter_route
uri:http://example.com
filters:
- name:RequestRateLimiter
args:
redis-rate-limiter.replenishRate: 10
redis-rate-limiter.burstCapacity: 20
注释:
redis-rate-limiter过滤器有两个配置属性:
replenishRate:令牌桶中令牌的填充速度,代表允许每秒执行的请求数
burstCapacity:令牌桶的容量,也就是令牌桶最多能容纳的令牌数。表示每秒用户最大能够执行的请求数量
Retry GatewayFilter Factory
该过滤器为请求重试过滤器,当后端服务不可用时,网关会根据配置参数来发起重试请求
spring:
cloud:
gateway:
routes:
- id:retry_route
uri:http://example.com
predicates:
- Path=/example/**
filters:
- name: Retry
args:
retries: 3
status:503
- StripPrefix=1
注释:RetryGatewayFilter提供4个参数来控制重试请求,参数说明如下:
retries:请求重试次数,默认值是3
status:HTTP请求返回的状态码,针对指定状态码进行重试
methods:指定HTTP请求中哪些方法类型需要进行重试,默认值是GET
series:配置错误码段,表示符合某段状态码才发起重试,默认值是SERVER_ERROR(5),表示 5XX段的状态码都会发起重试
3.GlobalFilter
全局过滤链的执行顺序
当Gateway接收到请求时,Filtering Web Handler处理器会将所有的GlobalFilter实例及所有路由上所配置的GatewayFilter实例添加到一条过滤器链中,该过滤器链里的所有过滤器都会按照@Order注解所指定的数字大小进行排序
Spring Cloud Gateway内置的全局过滤器也有很多,比如:
- GatewayMetricsFilter,提供监控指标
- LoadBalancerClientFilter,整合Ribbon针对下游服务实现负载均衡
- ForwardRoutingFilter,用于本地forward,请求不转发到下游服务器
- NettyRoutingFilter,使用Netty的HttpClient转发HTTP、HTTPS请求
六、Spring Cloud Gateway集成Nacos实现请求负载
Nacos可以用于实现Spring Cloud Gateway中网关动态路由功能,也可以基于Nacos来实现对后端服务器的负载均衡。前者是利用Nacos配置中心功能,后者利用Nacos服务注册功能
七、Spring Cloud Gateway集成Sentinel网关限流原理
- 通过GatewayRuleManager加载网关限流规则到GatewayFlowRule时,无论是否针对请求属性进行限流,Sentinel底层都会将网关流控规则GatewayFlowRule转化为热点参数规则ParamFlowRule存储在GatewayFlowManager中,与正常的热点参数规则相互隔离。在转化时,Sentinel会根据请求属性配置,为网关流控规则设置参数索引(idx),并添加到生成的热点参数规则中
- 在外边请求进入API网关时,会先经过SentinelGatewayFilter,在该过滤器中依次进行Route ID/API分组匹配、请求实现解析和参数组装
- Sentinel根据配置的网关限流规则来解析请求属性,并依照参数索引顺序组装参数数组,最终传入SphU.entry(name,args)中
- 在Sentinel API Gateway Adapter Common模块中在Slot Chain中添加一个GatewayFlowSlot,专门用来处理网关限流规则检查
- 如果当前限流规则并没有指定限流参数,则Sentinel会在参数的最后一个位置置入一个预设的常量,最终实现普通限流
注:实际上,在网关限流中,我们所配置的网关限流规则最终都会转化为参数限流规则,通过ParamFlowChecker.passCheck进行参数限流规则检查