日期:2023-10-06 03:29
本文主要从七点来谈网关,分别是网关的基本概念、网关设计思路、网关设计重点、流量网关、业务网关、常见网关的比较。熟悉基本概念的朋友可以根据目录查看自己的感受。有趣的部分。
网关,很多地方都把网关称为门,没有问题,但是需要区分网关和网桥的区别
「网桥」:工作在数据链路层,在不同或相同类型的局域网之间存储和转发数据帧,并在必要时进行链路层的协议转换。可以连接两个或多个网络,并且可以在它们之间发送信息包。
“网关”:这是一个很大的概念。它并不具体指某一类型的产品。只要它连接两个不同的网络,就可以称为网关。网桥一般只转发信息,而网关可能会封装信息。
根据网关特性,例如:
假设你想去群里的老大(这里只是举个例子)。谁都知道,老大绝对不是一个想见他就能见的人。他也害怕坏人。然后你就去老板所在的办公楼。如果是集团总部,这栋大楼的门就是角色的门户。通常看门员就在门口。看门员会做什么?
首先,所有想见boss的人都必须从这扇门进入(“统一入口”)。这扇门相当于将办公室与外界隔绝了。主要是为了保护内部安全和正常工作。到了这个门后,门卫肯定会要求你出示相关证件(“认证测试”),意思是判断你见老板的要求是否合理。如果无理取闹,他会直接拒绝,让你回家等消息。如果经过身份验证后,你发现你只是找老板谈二元店的生意,门卫会告诉你,没必要和老板谈。你可以直接去团投部门(【动态路由”,将请求路由到不同的后端集群),这时候它会帮你做一些“打包”,比如比如给你发一张通行证,然后告诉你怎么走等等。
看,网关的作用就是这三个。最终目标是减少你和团队之间的耦合。具体在计算机上,就是减少客户端和服务器之间的耦合。如果没有网关,则意味着所有请求都会被直接调用。服务器上的资源耦合度太高。如果服务器出现问题,客户端会直接报错。比如,老板换了工作地点。如果没有传送门,直接去原来的地方寻找的话,肯定会被告知boss不在这里。
使用单体应用程序架构时,客户端(Web 或移动设备)通过对后端应用程序进行 REST 调用来获取数据。负载均衡器将请求路由到 N 个相同的应用程序实例之一。然后,应用程序查询各种数据库表并将响应返回给客户端。在微服务架构下,单个应用被切分成多个微服务。如果所有的微服务都直接暴露于外界,必然会出现各种安全问题。此外,内部和外部耦合严重。
客户端可以直接向各个微服务发送请求。主要问题如下:
客户端需求与每个微服务公开的细粒度 API 之间不匹配。
某些服务使用的协议不是 Web 友好协议。可以使用Thrift二进制RPC,或者可以使用AMQP消息传递协议。
微服务很难重构。如果合并两个服务,或者将一个服务拆分为两个或多个服务,这种类型的重构会非常困难。
服务器端的每个服务都直接暴露给客户端调用,这必然会导致各种问题。同时,服务器端各个服务的扩展性和扩展性较差。 API网关是微服务架构中的基础组件,位于接入层下方、业务服务层上方。上述这些功能都适合在API网关中实现。
回到我们的服务器,下图介绍了Gateway的作用。可见,Gateway模式下的架构可以细到为每个服务实例配置自己的Gateway,也可以粗到配置一组服务。一,您甚至可以为整个架构配置一个访问网关。如此一来,整个系统架构的复杂性就会变得简单且可控。
此图为多层网关架构,其中有一个通用网关,访问所有流量(「流量网关」)并分发到不同的子系统,还有一个二级网关作为各子系统的接入网关(「业务网关」)。可见,网关管理的服务粒度可以是粗的,也可以是细的。通过网关,我们可以将分布式架构组织成星型架构,网络路由和分发服务请求。我们来说说一个好的网关应该具备哪些功能,这就是网关设计模式。
网关需要具备以下功能:
网关必须具备请求路由功能。这样对于调用端来说也是一件非常方便的事情。因为调用端不需要知道自己需要使用的其他服务的地址,所以全部交给Gateway处理。
为了能够代理后续服务并将请求路由到正确的位置,网关应该具有服务注册功能,即后端服务实例可以注册和注销其提供服务的地址。一般来说,注册就是注册一些API接口。例如,HTTP Restful请求可以注册相应API的URI、方法和HTTP标头。这样,网关就可以根据收到的请求中的信息来决定路由哪个后端服务。
由于一个网关可以接收多个服务实例,因此网关还需要在每个对端服务实例上实现负载均衡策略。更简单的一种是直接进行Round-Robin轮询。对于比较复杂的,可以设置分配的权重。对于更复杂的,还可以实现会话粘附。
网关在弹性设计上还可以实现异步、重试、幂等、流控、断路器、监控等。这样就和Service Mesh一样,应用服务可以只关心自己的业务逻辑(或者数据平面上的东西)而不是控制逻辑(控制平面)。
SSL加密和证书管理,会话验证、授权、数据验证,防止对请求源的恶意攻击。错误处理位置越高越好。因此,网关可以作为全站点的访问组件来保护后端服务。当然,网关还可以做更多有趣的事情,比如灰度发布、API聚合、API编排等。
「灰度释放」
网关可以完全导流同一服务不同版本的实例,并且还可以收集相关数据。这对于提高软件质量乃至产品试错都有非常积极的意义。
「API聚合」
使用网关将多个单独的请求聚合为单个请求。在微服务系统的架构中,由于服务变小,一个明显的问题是客户端可能需要多次请求才能获取所有数据。因此,客户端和后端之间的频繁通信可能会对应用程序的性能和规模产生非常负面的影响。因此,我们可以让网关帮助客户端请求多个后端服务(在某些场景下,完全可以并发个请求),然后将后端服务的响应结果组装起来,将它们发送回客户端(当然,这个过程也可以异步进行,但这需要客户端的配合)。
「API编排」
同样在微服务架构下,要完成一个完整的业务流程,我们需要调用一系列的API,就像工作流一样。该业务流程可以通过网页来编排。我们可以通过 DSL 定义和编排不同的 API,也可以通过 AWS Lambda 服务等方法连接不同的 API。
网关设计重点关注三个要点,高性能、高可用、高扩展性:
从技术设计上来说,网关不应该也不可能成为性能瓶颈。为了高性能,最好使用 C、C++、Go 和 java 等高性能编程语言来实现。网关对后端请求以及对前端 的请求的服务必须使用异步非阻塞 I/O,以确保后端延迟不会导致应用程序出现性能问题。 C、C++请参考linux下的epoll以及Windows的I/O完成端口的异步IO模型,Java如Netty,springReactor的蔚来框架。
因为所有的流量或者呼叫都经过网关,所以网关必须成为一个高可用的技术组件,它的稳定性直接关系到所有服务的稳定性。如果网关没有设计好,就会成为单点故障。因此,一个好的网关至少必须做到以下几点。
「聚类」 .网关要成为集群,最好自己组成一个集群,自己同步集群数据,而不需要依赖第三方系统来同步数据。
「服务为本」。网关还需要能够不间断地修改配置。一是像Nginx重载配置,可以实现不间断服务,二是最好是面向服务的。换句话说,您必须拥有自己的管理 API 才能在运行时修改您的配置。
「继续」 .比如重启就是像Nginx一样优雅重启。有一个处理请求分发的主进程。当我们需要重新启动时,新的请求被分配给新的进程,旧的进程在处理完正在处理的请求后退出。
因为网关需要处理所有的业务流量和请求,所以一定会有或多或少的业务逻辑。而且我们都知道业务逻辑是多变且不确定的。比如你需要在网关中添加一些业务相关的东西。因此,一个好的网关还需要具备可扩展性和二次开发能力。当然,也可以像Nginx一样通过Module进行二次开发。
另外,在“运维”方面,网关应具备以下设计原则。
「业务松耦合,协议紧耦合」 .在业务设计上,网关不应该与后续服务形成服务耦合,也不应该具有业务逻辑。网关应该是网络应用层的一个组件。它不应该处理通信协议主体,而应该只解析和处理通信协议头。此外,网关不应依赖于服务发现以外的第三方服务。
「应用监控,提供分析数据」 .网关需要考虑对应用性能的监控。除了对应后端服务的高可用统计外,还需要利用Tracing ID实现分布式链路跟踪,统计一定时间内各个API的吞吐量和响应时间。并返回代码以启动弹性设计中的相应策略。
「弹性设计保护后端服务」 .网关必须实现断路器、限流、重试、超时等弹性设计。如果一个或多个服务调用花费的时间太长,则可以超时并返回部分数据,或者返回上次成功请求中缓存在网关中的数据。你可以考虑一下这个设计。
「DevOps」。由于网关组件非常重要,因此需要像 DevOps 这样的东西来最大程度地减少其失败的可能性。该软件需要经过复杂的测试,包括功能和性能测试以及浸泡测试。还需要一系列自动化运维管控工具。
不要将聚合后端服务功能构建到网关的代码中,而是考虑将聚合服务放置在网关核心代码之外。可以使用Plugin,也可以放在网关后面,形成Serverless服务。
网关应靠近后端服务,并与后端服务使用同一内网。这样可以保证网关和后端服务调用的低延迟,减少很多网络问题。这里还要说一下,网关处理的静态内容应该靠近用户(应该放在CDN上),而此时的网关和动态服务应该靠近后端服务。
网关也需要扩容,所以需要成为集群来共享前端带来的流量。这可以通过 DNS 轮询、CDN 流量调度或通过具有更高性能的较低级别负载平衡设备来实现。
对于服务发现,可以做一个持续时间不长的缓存,这样就不需要每次请求的时候都去检查相关服务位于哪里。当然,如果你的系统并不复杂,可以考虑将服务发现功能直接集成到网关中。
考虑网关的舱壁设计方法。使用不同的网关来服务不同的后端服务,或者使用不同的网关来服务不同的前端客户。
另外,由于网关是用户请求和后端服务的桥梁设备,因此还需要考虑一些安全问题。详情如下:
「加密数据」。 SSL相关证书可以放置在网关上,由网关进行统一的SSL传输管理。
「验证用户的请求」 .在网关上可以做一些基本的用户验证,比如用户是否登录、用户请求中的token是否合法等。但是,我们需要权衡网关是否需要验证用户的输入。因为这样网关就需要从只关心协议头转变为关心协议体。一方面,协议体中的东西并不像协议头那么标准。另一方面,解析协议体需要大量的运行时间,从而降低了网关的性能。对此,我想说的是,根据具体需求,一方面,如果协议体是标准的,那么就可以做到;另一方面,如果协议主体是标准的,那么就可以做到。另一方面,对于解析协议带来的性能问题,需要做相应的隔离。
「检测异常访问」。网关需要检测一些异常访问,例如在较短的时间内请求数量超过一定值;例如,来自同一客户端的4xx请求的错误率太高了……对于这样的请求访问,网关一方面必须请求被阻止,另一方面需要发出警告,这可能会导致一些重大的安全问题,例如受到黑客的攻击。
流量网关,顾名思义,就是控制进入集群的流量的网关。这一步需要做很多工作。对于一个服务集群来说,必然存在很多非法请求或者无效请求。此时,请求必须被拒绝。减少集群的流量压力。
定义一个与具体后端业务应用和服务无关的全局策略网关,就是上图所示的架构模型——流量网关。流量网关通常只关注全局的API管理策略,比如全局流量监控、日志记录、全局流量限制、黑白名单控制、业务系统访问请求的负载均衡等,有点类似于防火墙。 「Kong是一个典型的流量网关。」
以下是kong的架构图,来自官网:https://www.introzo.com
这里需要补充的是,业务网关一般部署在流量网关之后、业务系统之前,并且比流量网关更靠近业务系统。通常API网络指的是业务网关。有时我们也会模糊流量网关和业务网关,让一个网关承担全部工作,所以两者之间没有严格的界限。
当单个应用拆分成很多微服务应用时,也会带来一些问题。一些与业务关联性不强的功能,如权限控制、日志输出、数据加密、熔断和限流等,是每个微服务应用都需要的,因此存在大量的重复代码实现。而且,由于系统的迭代和人员的更替,这些功能在各个微服务中的实现细节存在很大差异,导致维护成本更高。另一方面,原本在单一应用下非常容易做到的界面管理,在服务拆分后不再有集中管理的地方。无法统计存在哪些接口、接口定义是什么、运行状态如何。
网关就是为了解决以上问题。作为微服务系统中的核心基础设施,一般需要具备接口管理、协议适配、熔断限流、安全防护等功能。各种开源网关产品(如zuul)提供了优秀且高度可扩展的架构。可以轻松实现我们需要的一些功能,比如认证、日志监控、断路器、限流等。
与流量网关对应的是业务网关。业务网关更贴近我们的业务,即与服务器应用层打交道。那么应用层需要考虑的还有很多可以依赖业务网关的东西,比如线程模型、协议等。适配、熔断限流、服务编排等。我们看一下业务网关架构:
从这个旅程中,我们可以看到业务网关的主要职责和东西。目前业务网关比较成熟的API网关框架产品有Zuul1、Zuul2和Spring云网关,后面会讲到。比较。
既然是比较,我们就先对各种网关有一个宏观的了解,然后再选择一些常用的或者广泛使用的进行详细的了解。
目前常见的开源网关按照语言大致分为以下几类:
按照使用次数、成熟度等来划分,主流有5种:
OpenResty 是一个流量网关。根据前面对流量网关的介绍,你就可以知道流量网关的指责了。
OpenResty 是一个基于 Nginx 和 Lua 的高性能 Web 平台。它集成了大量复杂的Lua库、第三方模块和大部分依赖项。用于轻松构建动态 Web 应用程序、Web 服务和动态网关,这些应用程序、Web 服务和动态网关可以处理超高并发性 并且具有极高的可扩展性。
通过结合许多精心设计的Nginx模块,OpenResty有效地将Nginx服务器转变为强大的Web应用服务器。基于它,开发者可以使用Lua编程语言来实现Nginx核心以及现有的各种Nginx C模块。脚本编程构建极高性能的Web应用程序,可以处理超过10,000个并发请求
OpenResty 最初是顺应 OpenAPI 的潮流而做出的,所以 Open 的意思是“开放”,Resty 的意思是 REST 风格。虽然后来,任何形式的Web服务或者传统的Web应用都可以基于ngx_openresty来实现。
也就是说,Nginx不再是一个简单的静态Web服务器,也不是一个简单的反向代理。第二代openresty致力于通过一系列nginx模块将nginx扩展为功能齐全的Web应用服务器。
ngx_openresty是一个用户驱动的项目,后来也有很多国内用户参与。从www.introzo.com的点击量分布来看,国内外的点击量基本持平。
ngx_openresty 目前有两个主要的应用目标:
通用 Web 应用程序服务器。在这个目标下,现有的Web应用技术或多或少可以认为与OpenResty类似,比如Nodejs、PHP等。ngx_openresty的性能(包括内存使用和CPU效率)是最大的卖点之一。
Nginx 的脚本扩展编程,用于构建灵活的 Web 应用程序网关和 Web 应用程序防火墙。 NetScaler 有点类似。 Lua 编程的优点在于提供了巨大的灵活性。
Kong是基于OpenResty开发的,也是一个流量层网关。它是一个云原生、快速、可扩展的分布式 API 网关。它继承了OpenResty的高性能、易扩展等特点。 Kong只需添加机器节点即可轻松水平扩展。同时功能是插件化的,可以通过插件来扩展其能力。它可以在任何基础设施上运行。具有以下特点:
「Kong解决了什么问题」
当我们决定用微服务改造应用程序时,应用程序客户端如何与微服务交互的问题也随之而来。毕竟服务数量的增加会直接导致部署授权、负载均衡、通信管理、分析和变更。难度增加。
面对以上问题,API GATEWAY是一个很好的解决方案。它提供的访问限制、安全、流量控制、分析监控、日志、请求转发、综合和协议转换等功能可以让开发者集中精力。专注于具体逻辑的代码,而不是花时间思考如何解决应用程序与其他微服务的连接问题。
图片来自Kong官网:
可以看到Kong解决的问题。专注于全局API管理策略、全局流量监控、日志记录、全局流量限制、黑白名单控制、业务系统访问请求负载均衡等。
「Kong的优势与表现」
在众多API GATEWAY框架中,Mashape开源的高性能、高可用的API网关和API服务管理层——KONG(基于NGINX+Lua)的特点尤为突出。它可以通过插件扩展现有的功能。这些插件(使用lua编写)在API请求响应循环的生命周期内执行。同时,KONG本身提供了包括HTTP基本认证、密钥认证、CORS、TCP、UDP、文件日志、API请求限流、请求转发和NGINX监控等基础功能。目前,Kong 在 Mashape 管理着超过 15,000 个 API,每月支持 200,000 名开发人员处理数十亿个请求。
「香港建筑」
Kong提供了一系列的服务,所以我们不得不说一下内部结构:
首先底层是基于Nginx的。 Nginx是一个高性能的基础层,有很好的负载均衡和反向代理。然后在此基础上添加Lua脚本库,形成OpenResty,拦截请求并响应生命周期。脚本可以通过Lua来编写,所以插件也比较丰富。
关灯