java 单机接口限流处理方案
706
2022-07-11
API 网关选型及包含 BFF 的架构设计
一 背景介绍
下图是我从网络上找到的一个微服务架构的简单架构图,如图可见 API Gateway 在其中起到一个承上启下的作用,是关键组件。
图片来源于网络
在更通用的场景下我们会使用 NGINX 这样的软件做前置,用来处理SLB负载均衡过来的流量,作用是反向代理、集群负载均衡、转发、日志收集等功能。
然后再将 NGINX 的请求 proxy 到 API Gateway 做统一网关处理。
在上面的这个场景下 API Gateway 可以包含以下功能:
安全
限流
缓存
熔断
重试
负载
反向路由
认证、鉴权
日志收集和监控
其他
熟悉 NGINX 的朋友应该可以看出来,上面列出的这些功能和 NGINX 的部分功能是重合的,不过由于架构结构不同,在上面我提到的场景中,即 NGINX 在前 API gateway 在后的结构中,他们两者关注的维度也不一样,所以即使有重合也正常。
二 架构调整
下图是我基于云原生微服务架构设计的架构图其中前端流量是通过 SLB -> NGINX -> API Gateway 再到具体服务。
三 java技术栈的 API Gateway 选型
由于后端采用java 的 spring cloud 开发的,所以在语言一致性上更倾向 java 语言开发的组件。如上图虽然在 API Gateway 的位置上写的是 spring cloud gateway,然而也可以采用像 zuul、zuul2 这些同样是 java 语言开发的组件。对于具体 zuul 和 spring gateway的选型,是这样考虑的:
spring cloud gatewayzuul性能性能比 Netflix Zuul 好将近一倍Zuul1 的性能较差 Zuul2 较 Zuul1 有较大的提升社区和文档spring社区非常活跃一般可维护性基于spring官方维护性强经常跳票、Spring Cloud暂时还没有对Zuul2.0的整合计划亮点异步、配置灵活成熟、简单门槛低不足早期产品、新版本踩坑性能一般、可编程一般
Spring Cloud Gateway 的性能比 Zuul 好基本上已经是业界公认的了,实际上,Spring Cloud Gateway 官方也发布过一个性能测试,这里节选如下数据:
Spring Cloud Gateway 构建于 Spring 5+,基于 Spring Boot 2.x 响应式的、非阻塞式的 API。同时,它支持 websockets,和 Spring 框架紧密集成。从目前来看,gateway替代zuul是趋势。基于以上这些,综合考虑在架构中使用Spring Cloud Gateway。
四 非java技术栈的 API Gateway 选型
现代 API Gateway 越来越需要或者流行可编程网关了。上面介绍的都是基于 java 语言开发的可编程的 API Gateway。下面我们来聊聊非 java 语言开发的网关。从前面的架构图上看,我们完全可以将 NGINX 和 API Gateway 合并起来,他们的功能的重合点自然消除了,也能降低架构的复杂性和运维成本。
NGINX 是一款优秀的软件,然而它在动态性方面的不足导致不太灵活,后面出现的 OpenResty、tengine 这些基于NGINX 和 Lua 的软件在动态性、灵活方面有本质上的改善,加上基于Lua脚本和插件,可以实现所谓的可编程。
市面上基于OpenResty 以 API Gateway 为应用场景的应用软件有 Kong、APISIX、tyk 等。以下是CNCFland scape 的一个概览
比较了一下 NGING 和 KONG
经过考虑,在架构上,后期有可能将 NGINX、Spring Cloud Gateway 替换成KONG 或其他软件。
比较了一下,目前最火的应用是Kong,另一个国产的 APISIX 趋势也是很猛,且他们的技术栈雷同,所以我在选型上找到了APISIX的作者做的对比:
从 API 网关核心功能点来看,两者均已覆盖:
更详细的比较:
通过性能测试可以看到,在不开启插件的情况下,Apache APISIX 的性能(QPS 和延迟)是 Kong 的2倍,但开启了两个常用插件后,性能就是 Kong 的十倍了。
无论从性能、可用性、可编程代码量等各个维度APISIX都是非常优秀的,目前唯一担心的就是这种早期项目没有太多大规模应用实践,如果上生产还是有风险,可在测试环境调研,并等待有更多生产实践作为依据。 当然如果架构师认为风险并不大,且经过了测试调研也是可以上的。😁
五 BFF 层建设迭代
前面我们将 API Gateway 的网关选型介绍了一下,请求通过网关后一般不会直接打到具体微服务上的,而是会通过BFF层,所谓的BFF,即 backend for frontend 面向前端的后端。具体来说它的职能包括:
api数据裁剪
接口编排
接口调用
这层有的公司会按业务进行多个BFF的建设,在BFF中又有可能拆成多个服务,比如支撑首页的,支持列表页的,或者只有一个服务,支撑某个应用的所有请求的。
有了BFF层,前后端就会更好的解耦,前端不用再调用多个接口,然后再组织数据,微服务后端也只需要关心自己服务边界内的事情。
然而在实践的过程中会出现一些问题:
大量业务逻辑从前后端集中在了BFF层
BFF层逻辑复杂,代码量越来越大,难以维护
BFF API版本维护复杂
前端端接口职责不清,扯皮的结果就是放在BFF层
以上是我真实遇到过的场景。所以在后面的架构设计和实施中,这些情况会尽量避免,但没有从技术上解决根本问题。直到 GraphQL 的出现,让我眼前一亮,给了我一个很好的解决方案。关于GraphQL的搭建,数据交换等细节这里就不展开说了,感兴趣的可以从网上找到很多资料。
下图是我从网络上找的一个符合我心目中的理想架构。
图片来源于网络
说起来简单,做起来没那么容易 ,细节是魔鬼,每利用一个新的技术都会经历一波打怪升级的过程。不过总体来说利用GraphQL确实能从理论上解决上面所说的问题。而重点是如何将它结合进你的系统架构中,并且发挥出它的优势。架构很多时候是在做权衡和选择
网关的定义
网关(Gateway)又称网间连接器、协议转换器。顾名思义,网关(Gateway)就是一个网络连接到另一个网络的“关口”。网关在传输层上以实现网络互连,是最复杂的网络互连设备,仅用于两个高层协议不同的网络互连。
1
网关的结构
网关的结构也和路由器类似,不同的是互连层。网关既可以用于广域网互连,也可以用于局域网互连。
2
网关的功能
网关是一种充当转换重任的计算机系统或设备。在使用不同的通信协议、数据格式或语言,甚至体系结构完全不同的两种系统之间,网关是一个翻译器。
与网桥只是简单地传达信息不同,网关对收到的信息要重新打包,以适应目的系统的需求。同时,网关也可以提供过滤和安全功能。大多数网关运行在OSI 7层协议的顶层--应用层。
3
网关的分类
在OSI中,网关有两种:一种是面向连接的网关,一种是无连接的网关。当两个子网之间有一定距离时,往往将一个网关分成两半,中间用一条链路连接起来,我们称之为半网关。
按照不同的分类标准,网关也有不同种类。TCP/IP协议里的网关是最常用的,在这里我们所讲的“网关”均指TCP/IP协议下的网关。
网关的实质
网关实质上是一个网络通向其他网络的IP地址。
比如有网络A和网络B,网络A的IP地址范围为“192.168.1.1~192. 168.1.254”,子网掩码为255.255.255.0;网络B的IP地址范围为“192.168.2.1~192.168.2.254”,子网掩码为255.255.255.0。
在没有路由器的情况下,两个网络之间是不能进行TCP/IP通信的,即使是两个网络连接在同一台交换机(或集线器)上,TCP/IP协议也会根据子网掩码(255.255.255.0)判定两个网络中的主机处在不同的网络里。
而要实现这两个网络之间的通信,则必须通过网关。
如果网络A中的主机发现数据包的目的主机不在本地网络中,就把数据包转发给它自己的网关,再由网关转发给网络B的网关,网络B的网关再转发给网络B的某个主机。网络B向网络A转发数据包的过程。
对默认网关,其意思是一台主机如果找不到可用的网关,就把数据包发给默认指定的网关,由这个网关来处理数据包。现在主机使用的网关,一般指的是默认网关。所以说,只有设置好网关的IP地址,TCP/IP协议才能实现不同网络之间的相互通信。
在日常工作中,不同的场合下,我们可能听说过很多次网关这个名称,这里说的网关特指API网关(API Gataway)。字面意思是指将所有API的调用统一接入API网关层,由网关层负责接入和输出。
那么在什么情况下需要一个API网关呢?下面从单体应用到微服务演变的过程去阐述,回顾单体应用时代,在业务简单、团队组织规模很小的时候,我们常常把功能都几种与一个应用中,统一部署,统一测试,如下图:
随着业务的迅速发展,组织成员日益增多。将所有的功能几种在一个Tomcat中的时候,没更新一个功能模块,势必要更新所有的程序。牵一发而动全身,系统将很难维护。
单体应用满足不了日趋增长的需求之后,微服务出现了。我们利用微服务的思想,将原来的单体应用进行微服务化。将原来集中于一体的功能(如商品、订单服务)进行拆分,每个功能模块又各自的自成体系的发布、运维等功能。这样就解决了单体应用的弊端,如下:
这时,我们还没有看到API Gateway。举例来说,原先IOS、Android、PC客户端调用服务的地方,需要多个URL地址,有订单的、商品的、用户的。微服务化后就必须有统一的出入口,这种情况下,API Gateway就出现了。API Gateway很好的解决了微服务下调用、统一接入等问题,如下图所示:
有了API网关之后,各个API服务提供团队可以专注于自己的业务逻辑处理,而API罔顾赞更专注于安全、流量、路由等问题。
看到上面的图示与描述,我们可能会想到另外一个与网关类似的东西——代理。网关与代理的区别:代理是纯粹的数据透传,协议不会发生变化;网关在数据透传的背景下,还会设计协议的转换,比如上图中用户请求传输到网关的协议是HTTP,通过网关透传到下游则可能已经转换成企业内部的RPC了(比如JSF、Dubbo等企业自研的RPC框架)。
一个API网关的基本功能包含了统一接入、协议适配、流量管理与容错、以及安全防护,这四大基本功能构成了网关的核心功能。网关首要的功能是负责统一接入,然后将请求的协议转换成内部的接口协议,在调用的过程中还要有限流、降级、熔断等容错的方式来保护网关的整体稳定,同时网关还要做到基本的安全防护(防刷控制),以及黑白名单(比如IP白名单)等基本安全措施,如下图所示:
除了基本的四大功能,网关运行良好的环境还包括注册中心(比如:ZK读取已发布的API接口的动态配置)。为了实现高性能,将数据全部异构到缓存(如:Redis)中,同时还可以配合本地缓存来进一步提高网关系统的性能。为了提高网关的吞吐率,可以使用NIO+Servlet 3 异步的方式,还可以利用Servlet 3 的异步特性将请求线程与业务线程分开,为后续的线程池隔离做好基本的支撑。访问日志的存储我们可以放到Hbase中,如果要作为开放网关使用,那么需要一个支持OAuth2.0的授权中心。还可以引入Nginx + lua的方式将一些基本的校验判断放到应用系统之上,这样可以更轻量化的处理接入的问题,整体的网关架构示例如下所示:
文章中,我们从单体系统到微服务系统演变,引入了API网关的概念,紧接着介绍了API Gateway的基本功能,以及展示一个线上生产网关的架构示意图。通过本片文章,可以对API Gateway的内容有一个基本的认知
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~