1、API网关的作用,为什么要用API网关?
不使用网关的问题
- 服务将所有 API 接口对外直接暴露给用户端,这本身就是不安全和不可控的,用户可能越权访问不属于它的功能。
- 后台服务可能采用不同的通信方式,如服务 A 采用 RESTful 通信,服务 B 采用 RPC 通信,不同的接入方式让用户端接入困难。尤其是 App 端接入 RPC 过程更为复杂。
- 在服务访问前很难做到统一的前置处理,如服务访问前需要对用户进行鉴权,这就必须将鉴权代码分散到每个服务模块中,随着服务数量增加代码将难以维护。
采用网关的好处:
针对所有请求进行统一鉴权、熔断、限流、日志等前置处理,让微服务专注自己的业务。 统一调用风格,通常 API 网关对外提供 RESTful 风格 URL 接口。
2、谓词(Predicate)与过滤器(Filter)
前端应用发来的请求要被转发到哪个微服务上,是由谓词决定的;而转发过程中请求、响应数据被网关如何加工处理是由过滤器决定的。
有哪些常见的谓词配置?
After 代表在指定时点后路由规则生效。
复制代码
predicates:
- After=2020-10-04T00:00:00.000+08:00
Before 代表在指定时点前路由规则生效。
复制代码
predicates:
- Before=2020-01-20T17:42:47.789-07:00[America/Denver]
Path 代表 URI 符合映射规则时生效。
复制代码
predicates:
- Path=/b/**
Header 代表包含指定请求头时生效。
复制代码
predicates:
- Header=X-Request-Id, \d+
这里额外解释下,如果请求具有名为 X-Request-Id 的 Header,其值与\d+正则表达式匹配(具有一个或多个数字的值),则该路由匹配。
Method 代表要求 HTTP 方法符合规定时生效。
复制代码
predicates:
- Method=GET
常见的过滤器配置:
AddRequestParameter 是对所有匹配的请求添加一个查询参数。
复制代码
filters:
- AddRequestParameter=foo,bar #在请求参数中追加foo=bar
AddResponseHeader 会对所有匹配的请求,在返回结果给客户端之前,在 Header 中添加响应的数据。
复制代码
#在Response中添加Header头,key=X-Response-Foo,Value=Bar。
filters:
- AddResponseHeader=X-Response,Blue
Retry 为重试过滤器,当后端服务不可用时,网关会根据配置参数来发起重试请求。
复制代码
filters:
#涉及过滤器参数时,采用name-args的完整写法
- name: Retry #name是内置的过滤器名
args: #参数部分使用args说明
retries: 3
status: 503
以上片段含义为,当后端服务返回 503 状态码的响应后,Retry 过滤器会重新发起请求,最多重试 3 次。
3、SpringCloud Gateway的执行原理
Spring Cloud Gateway 启动时基于 Netty Server 监听指定的端口。当前端应用发送一个请求到网关时,进入 Gateway Handler Mapping 处理过程,网关会根据当前 Gateway 所配置的谓词(Predicate)来决定是由哪个微服务进行处理。
确定微服务后,请求向后进入 Gateway Web Handler 处理过程,该过程中 Gateway 根据过滤器(Filters)配置,将请求按前后顺序依次交给 Filter 过滤链进行前置(Pre)处理,前置处理通常是对请求进行前置检查,例如:判断是否包含某个指定请求头、检查请求的 IP 来源是否合法、请求包含的参数是否正确等。
当过滤链前置(Pre)处理完毕后,请求会被 Gateway 转发到真正的微服务实例进行处理,微服务处理后会返回响应数据,这些响应数据会按原路径返回被 Gateway 配置的过滤链进行后置处理(Post),后置处理通常是对响应进行额外处理,例如:将处理过程写入日志、为响应附加额外的响应头或者流量监控等。