Spring Cloud GateWay 原理
一、概述
在微服务架构中,每个服务都是一个可以独立开发和运行的组件,而一个完整的微服务架构由一系列独立运行的微服务组成。其中每个服务都只会完成特定领域的功能。各个微服务之间通过轻量级通信机制 REST API 或者 RPC 完成通信。
微服务之后在某些层面会带来一定的影响,比如,一个用户查看一个商品的详情,对于客户端来说,可能需要调用商品服务、评论服务、库存服务等多个服务来完成数据的渲染。
在这个场景中,客户端虽然能通过调用多个服务实现数据的获取,但是会存在一 些问题:
- 客户端需要发起多次请求,增加了网络通信的成本及客户端处理的复杂性。
- 服务的鉴权会分布在每个微服务中处理,客户端对于每个服务的调用都需要重复鉴权。
- 在后端的微服务架构中,可能不同的服务采用的协议不同,比如有 HTTP、RPC 等。客户端如果需要调用多个服务,需要对不同协议进行适配。
二、微服务网关的作用
所以,可以在微服务之前增加一个前置节点,这个节点就是网关,网关就是一个网络连接到另一个网络的“关口”。
而在微服务架构中,它不仅仅只是一个网络互连的一个关口,还有更多的作用,以前面分析的这个场景为例,增加网关之后。
增加了 API 网关之后,在 API 网关层可以把后端的多个服务进行整合,然后提供一个唯一的业务接口,客户端只需要调用这个接口即可完成数据的获取及展示。在网关中会再去消费后端的多个微服务进行统一的整合,给客户端返回一个唯一的响应。
当然,网关不仅只是做一个请求转发以及服务整合,有了网关这个统一的入口之后,它还能提供
- 针对所有请求进行统一鉴权、限流、熔断、日志。
- 协议转化。针对后端多种不同的协议,在网关层统一处理后以 HTTP 协议对外提供服务。
- 统一错误码处理。
- 请求转发,并且可以基于网关实现内外网隔离
总结网关的作用
-
性能:API高可用,负载均衡,容错机制。
-
安全:权限身份认证、脱敏,流量清洗,后端签名(保证全链路可信调用),黑名单(非法调用的限制)。
-
限流:流量控制,错峰流控,可以定义多种限流规则。
-
缓存:数据缓存。
-
日志:日志记录(spainid,traceid)一旦涉及分布式,全链路跟踪必不可少。
-
监控:记录请求响应数据,api耗时分析,性能监控。
三、常见的网关方案
- OpenResty(Nginx+lua)
- Kong,是基于openresty之上的一个封装,提供了更简单的配置方式。 它还提供了付费的商业插件
- Zuul,是spring cloud生态下提供的一个网关服务,性能相对来说不是很高
- Spring Cloud Gateway,是Spring团队开发的高性能网关
四、Spring Cloud Gateway的核心概念
4.1、Route 路由
它是网关的基础元素,包含ID、目标URI、断言、过滤器组成,当前请求到达网关时,会通过Gateway Handler Mapping,基于断言进行路由匹配,当断言为true时,匹配到路由进行转发
4.2、Predicate,断言
它可以允许开发人员去匹配HTTP请求中的元素,一旦匹配为true,则表示匹配到合适的路由进行转发,提供了多种方式的断言,当然也可以自定义
4.3、Filter,过滤器
可以在请求发出的前后进行一些业务上的处理,比如授权、埋点、限流等。
整体工作原理如下:
predicate就是我们的匹配条件;而filter,就可以理解为一个无所不能的拦截器。有了这两个元素,再加上目标uri,就可以实现一个具体的路由了。
客户端向 Spring Cloud Gateway 发出请求,如果请求与网关程序定义的路由匹配,则该请求就会被发送到网关 Web 处理程序,此时处理程序运行特定的请求过滤器链。
上图中过滤器之间用虚线分开的原因是过滤器可能会在发送代理请求的前后执行逻辑。所有 pre 过滤器逻辑先执行,然后执行代理请求;代理请求完成后,执行 post 过滤器逻辑。
Filter又分为全局过滤器GlobalFilter和路由过滤器RouteFilter。
使用案例
1、针对所有请求增加一个foo=bar的参数
2、RequestRateLimiterGatewayFilterFactory 默认提供了 RedisRateLimiter 的限流实现,它采用令牌桶算法来实现限流功能
redis-rate-limiter 过滤器有两个配置属性:
- replenishRate:令牌桶中令牌的填充速度,代表允许每秒执行的请求数。
- burstCapacity:令牌桶的容量,也就是令牌桶最多能够容纳的令牌数。表示每秒用户最大能够执行的请求数量。
3、Retry GatewayFilter Factory 为请求重试过滤器,当后端服务不可用时,网关会根据配置参数来发起重试请求
RetryGatewayFilter 提供 4 个参数来控制重试请求。
- retries:请求重试次数,默认值是 3
- status:HTTP 请求返回的状态码,针对指定状态码进行重试,比如,在上述配置中,当服务端返回的状态码是 503 时,才会发起重试,此处可以配置多个状态码。
- methods:指定 HTTP 请求中哪些方法类型需要进行重试,默认是 GET。
- series:配置错误码段,表示符合某段状态码才发起重试,默认值是 SERVER_ERROR(5),表示5xx 段的状态码都会发起重试。如果 series 配置了错误码段,但是 status 没有配置,则仍然会匹配 series 进行重试。