API网关你不知道的那些事情
干货:
网关模式是BFF模式吗
Facade模式与网关模式又有什么区别
API网关不只是代理或者路由
1. 客户端到微服务通信架构
在这种模式中,客户端应用程序可以直接向某些微服务发出请求。客户端通过微服务提供的一个公开的endpoint来访问,可以是域名也可以是IP+Port。这种方式比较简单粗暴,前期产品的迭代和开发效率高,也不用维护其他中间件组件(gateway,nacos等);但是缺点也很明显,比如我们看以下问题:
- 客户端应用程序如何最大限度地减少对后端的请求数量并减少与多个微服务的繁琐通信?
与多个微服务交互以构建单个UI页面会增加网络上的往返次数,也就是说这种模式会增加UI端的延迟和复杂性。理想情况下,聚合数据的响应应该在服务器端有效地聚合然后提供一个接口统一返回就行了,这样的方式就会减少响应延迟,UI在获取到数据之后会立刻渲染展示。 - 如何处理横切关注点,如授权、数据转换和动态请求分派?
我们从上图可以看出,我们每个微服务其实都对各个端提供了例如认证,授权,限流等之类的操作,对于服务端来说就是复制黏贴,但是对于客户端来说简直就是灾难,他们每对接一个微服务就得写一套处理服务端的认证鉴权逻辑,还得维护很多secret key。其实后端也挺痛苦的,他也得拷贝之前项目的认证授权模式在新项目中使用,完完全全在做无用功。再比如分布式链路追踪,trace_id的生成,每个后端服务都得搞一套,这不是XG吗,我们是人不是机器。还有就是我们在做灰度发布的时候,你总不能在端上搞吧,你总共有1000w用户,你想用100w人做灰度验证,你让客户端去做,那客户端同学绝笔回敬你一个白眼。既然你不想得罪他们你就在服务端去做,可是服务端有好几个微服务,你该如何去做灰度呢? - 如果服务端不是http/https等友好协议,是二进制协议咋办
客户端应用程序不支持服务器端使用的协议(如 AMQP 或二进制协议)。因此,请求必须通过 HTTP/HTTPS 等协议转换为其他协议。在这种情况下又该如何去做? - 如何打造一个专门为移动应用提供的服务呢?
多个微服务的API可能无法很好地满足不同客户端应用程序的需求。例如,移动应用程序的需求可能与PC应用程序的需求不同。对于移动应用程序来说,可能需要进一步优化以提高数据响应效率。我们可以通过聚合来自多个微服务的数据并返回一组数据来实现此功能,有时还可以在响应中过滤移动应用程序不需要的任何数据。当然,我们也可以压缩响应数据。像这样的聚合或者压缩数据等行为到底有谁来做是最合适的呢?
2. 引入API Gateway网关
上面的所有问题都靠API Gateway搞定,而且还有很多问题我们虽然没有提到,但是Gateway统统都可以帮你搞定。
2.1 什么是API网关模式
当你为多端应用程序提供服务而准备设计和构建庞大且复杂的基于微服务的后台应用程序的时候,可以考虑使用API Gateway。此模式是为特定微服务组提供单一入口点的服务。它类似于面向对象设计中的Facade模式,但在本例中,它是分布式系统的一部分。API网关模式有时也被称为BFF模式
,因为我们在构建它时考虑了客户端应用程序的需求。
2.2 那什么是Facade模式?
Facade模式是面向对象编程中常用的软件设计模式。一个facade对象它作为一个前置接口,掩盖了更复杂的底层代码或结构代码。就比如linux操作系统的文件读写操作,林納斯·托瓦茲不可能给你复杂的读写文件逻辑,他就给你提供四五个简单的api,比如read,write,open and create等,人家没必要再给你解释inode是啥,段又是啥,文件句柄又是啥,这要解释下来没完没了,估计linux也不会发展到现在,作者有意屏蔽底层实现细节,提供高度抽象的api就是让你爱上linux,而不是唾弃这样伟大的产品。
所以这样看来Facade模式和网关模式没啥区别,都是提供单一入口点的服务,但是因为Api Gateway诞生于微服务架构体系中,所以它属于分布式系统架构中的一部分,进而在各大公司中发展壮大起来。
2.3 什么又是BFF模式?
BFF
模式我前面讲过了 ,大家回头可以看下。我这里也再说一遍:就是当你的app想要获取多个微服务去渲染一个页面的时候,这个过程会经过多次的网络请求,势必会增加延迟和复杂性,为了避免这一类问题的发生或者说减少这类问题的影响,我们在架构模式中抽离出来一种模式叫做BFF
模式,它专门用来做一件事情:就是根据app的请求模式,它先把所有要请求多个微服务的数据聚合任务在它这里做了,它本身也是一个微服务,所以可以对外提供一个接口就行了,这样app就不用请求多次了。就这么简单。
我们已经知道了什么是网关模式,那么很明显网关模式是属于BFF
中的一种,而BFF
会有很多种实现方式,这也就回答了前面第一个问题。
如下图显示了自定义API网关如何适配仅具有少量微服务的简化架构:
应用程序连接到单个服务,即API网关,该服务配置了路由转发规则,将请求转发到各个微服务。
这样我们就可以把鉴权,安全,限流,转换等与业务无关的逻辑在这个里面就做了,然后流量透传到后端微服务处理就行了,后端再也不用做跟业务无关的需求了。
但是上述方式有瓶颈,所有服务都经由一个API Gateway, 随着接入的业务越来越多,它不断的增长和演变,最终,它会因为这些不同的需求而变得臃肿,实际上它可能类似于单体应用程序或单体服务了,那这个时候就要小心了,它可能违反了微服务自治。
我们目前的做法就是把一个大的API Gateway根据业务边界和客户端应用程序进行隔离,拆分成一个个小的Gateway,这样我们就可以针对每个客户端应用程序的需求使用不同的Gateway。如下图,多个API Gateway:
基本上现有大公司的微服务架构都是这套模式,有的可能在API Gateway和微服务之间再加一个BFF,专门解决数据聚合的问题,但这都是基于这套基本的架构模式,因此掌握了这套架构,你就不是小白了。
3. API Gateway模式的主要特性
3.1 反向代理或路由
API网关提供了一个反向代理来将请求(第7层路由,通常是HTTP请求)重定向或路由到内部微服务。
3.2 请求聚合
作为网关模式的一部分,我们可以将针对多个客户端请求多个内部微服务的请求(通常是 HTTP 请求)聚合到一个Gateway中,当客户端页面需要来自多个微服务的信息时,这种模式特别方便。
3.3 插件管理
根据每个API Gateway产品提供的功能,我们可以将某些插件从网关中卸载或者设置上,例如如下功能:
- 认证和授权
- 服务发现
- 响应缓存
- 重试策略、降级
- 限流
- 负载均衡
- 链路追踪
- 协议转换
- 黑白名单
- 灰度发布
上面我们有说灰度发布,其实就是在API Gateway中做的,实现方式多样化,因为你都拿到流量了,想在这个上面灰度,你可以在header头中加一个标识,然后在Gateway中配置下灰度转发路由,这样你就将灰度流量转发到灰度环境了,而你的灰度环境也不要硬编码来判断那些人需要灰度以及header中是否有灰度标识。
我们这里的灰度标识就是落日志用的,为了统计灰度环境的稳定性和功能性的,有了这个标识就可以在日志中有了区分。
4. API Gateway缺点
- 单点故障
- 额外的网络调用,API网关可能会增加响应时间
- API网关设计不合理,扩展就很麻烦
- 如果API Gateway是由单个团队开发,可能会出现开发瓶颈
缺点都是随着业务的不断增长而不断变化的,拥抱变化才是好心态。
5. 小结
首先介绍了客户端直连微服务模式,其次介绍了API网关模式,其实不管是那种模式都是软件架构的正常迭代过程,可能下一代就会发生天翻覆地的变化,所以怀抱一颗真诚学习的心就是了,成长永不落后,怕的就是不敢于突破现在的自己,加油。