SpringCloud微服务之API⽹关设计(⼀)
前⾔
由于我们使⽤的服务系统架构,所以没办法像传统单体应⽤⼀样依靠数据库的 join 查询来得到最终结果,那么如何才能访问各个服务呢?按照微服务设计的指导原则,我们的微服务可能存在下⾯的问题:
服务使⽤了多种协议:因为不同的协议有不同的应场景⽤,⽐如可能同时使⽤ HTTP, AMQP, gRPC 等。
服务的划分可能随着时间⽽变化。
服务的实例或者Host+端⼝可能会动态的变化。
那么,对于前端的UI需求也可能会有以下⼏种:
粗粒度的API,⽽微服务通常提供的细粒度的API,对于UI来说如果要调⽤细粒度的api可能需要调⽤很多次,这是个不⼩的问题。
不同的客户端可能需要不同的数据。Web,H5,APP,OpenAPI
不同设备的⽹络性能,对于多个api来说,这个访问需要转移的服务端会快得多
以上,就是我们构建微服务的过程中可能会遇到的问题。
概念
API Gateway(API GW / API ⽹关),顾名思义,是企业 IT 在系统边界上提供给外部访问内部接⼝服务的统⼀⼊⼝。在微服务概念的流⾏之前,API⽹关的实体就已经诞⽣了,例如银⾏、证券等领域常见的前置机系统,它也是解决访问认证、报⽂转换、访问统计等问题的。
百度百科:API⽹关是⼀个服务器,是系统的唯⼀⼊⼝。从⾯向对象设计的⾓度看,它与外观模式类似。API⽹关封装了系统内部架构,为每个客户端提供⼀个定制的API。它可能还具有其它职责,如⾝份验证、监控、负载均衡、缓存、请求分⽚与管理、静态响应处理。
API⽹关⽅式的核⼼要点是,所有的客户端和消费端都通过统⼀的⽹关接⼊微服务,在⽹关层处理所有的⾮业务功能。通常,⽹关也是提供REST/HTTP的访问API。服务端通过API-GW注册和管理服务。
⽹关使⽤场景
API⽹关的流⾏,源于近⼏年来,移动应⽤与企业间互联需求的兴起。移动应⽤、企业互联,使得后台服务⽀持的对象,从以前单⼀的Web 应⽤,扩展到多种使⽤场景,且每种使⽤场景对后台服务的要求都不尽相同。这不仅增加了后台服务的响应量,还增加了后台服务的复杂性。
当应⽤架构是由⼀系列的微服务构建的时候,我们就应当考虑对外提供的服务如何与微服务进⾏交互。
我们根据使⽤场景分类⼤体如下:
Web App APIGateway 和 Mobile App APIGateway:
聚合作⽤:写简单的业务逻辑,跨多个service获取数据拼装结果。
在Mobile app产品信息页⾯仍然要展现很多的信息。例如,基本的产品信息,该页也会展⽰产品其他相关信息:
购物车;历史订单;顾客评论;低库存预警;运送选项;各种产品推荐;可替代的购买选项;
当使⽤单体应⽤架构时:
移动客户端通过给应⽤发送⼀个REST请求来获取数据,⽐如:
GET
负载均衡器路由这个请求到⼏个相同应⽤实例其中的⼀个。单体应⽤接着查询多个数据库表并返回响
应给客户端。
当使⽤微服务架构的时候:
显⽰在产品详细信息页⾯的数据来⾃于多个微服务。如下是⼀些潜在的服务,它们也有可以展⽰在特定产品信息页⾯的数据:
购物车服务、订单服务、⽬录服务、评论服务、库存服务、运送服务、推荐服务。
这个需要使⽤Mobile app API Gateway:它通常向移动客户端暴露出⼀个粗粒度的API。
API⽹关可以提供类似这样的接⼝:
GET
可以使移动客户端在⼀次调⽤中获取所有的产品信息。API⽹关通过调⽤多个服务—产品服务、推荐服务、评论服务等来处理请求,并封装结果。
优点:
解耦作⽤:它封装了应⽤的内部结构,客户端直接和⽹关通信,⽽不必调⽤特定的服务。
提供给每种客户端特定优化的API。
减少请求环路、简化客户端逻辑。⽐如说,API Gateway使得客户端⽤⼀次请求就可以从多个service处获取数据。
缺点:
必须被开发、部署和管理成⼀个⾼度可⽤的组件,也有成为开发瓶颈的危险。
为了暴露出每个微服务的,开发者必须更新API⽹关。
Partner OpenAPI:
转发路由作⽤:对外提供的接⼝服务,⼀般直接把请求转发到合适的service,但是此时的API GW需要增加配额、限流、令牌等⼀系列安全管控功能。对外提供隔离作⽤:请求路由,安全认证,负载均衡,限流、监控、权限控制等等。
API⽹关需要考虑的因素
安全性问题
企业在把服务暴露给外部使⽤时,⾸先要确保服务使⽤的安全,防⽌外部的恶意访问对公司业务的影响,特别是涉及交易⽅⾯的服务,更是要全⾯考虑安全性。为确保安全,需要考虑在通讯链路的建⽴、通讯数据的加密、数据的完整性、不可抵赖性等⽅⾯。
性能问题
作为企业API的⼊⼝,所有的请求都会经过API⽹关进⾏转发,可想⽽知,对API⽹关的访问压⼒是巨⼤的,有的⽹站甚⾄达到每分钟上千万的访问量。特别是在⼀些互联⽹企业,海量的移动终端每时每刻都需要与后端的服务进⾏交互,如果不能保证⽹关的⾼性能,企业在⽹关层需要投⼊⼤量的设备和成本。曾在⼀家互联⽹公司发⽣过,由于⽹关性能问题,⽹关的机器数量,需要与后台服务器的数量保持同步增长。这种情况显然是企业服务忍受的。
⾼可⽤问题
API⽹关作为逻辑上的单点,⼀旦发⽣问题,将造成企业服务的不可⽤,对企业来说可能造成的致命的影响。计算短时间的不可⽤,也会给企业带来直接的经济损失。所以,如何保证API⽹关的7*24⼩时的稳定运⾏,⽹关的⾃动伸缩、API的热更新等问题,都是企业级的⽹关需要考虑的
扩展性问题
前⾯说到,企业⽹关提供了⼀个脚⼿架,⼀些⾮功能性的问题,例如⽇志、安全、负载均衡策略、鉴权等。这些插件会随着企业业务规模等的变化进⾏不断的强化与调整。这就需要⽹关层提供这样⼀种机制,使得可以灵活地进⾏这些调整和变化,⽽不⽤频繁对⽹关层进⾏改动,确保⽹关层的稳定性。
API⾼效运维的问题
API在上线、发布过程中,都需要涉及到⽹关层的配合,例如,需要⽹关层知道API发布的地址,API的接⼝形式、报⽂格式,也需要⽹关层对后台API进⾏封装。在API调整后,需要作出相应的修改。所以,API⽹关设计时,需要明确⽹关层与服务层的职责切分与协作模式,使得API的管理、发布更加⾼效。
API全⽣命周期的管理
API服务的全⽣命周期,包括服务的开发、测试、上线发布;服务使⽤的申请、开通;服务分类分级别的管理、服务使⽤情况的监控、计费等等。
⼀个企业可能会暴露成百上千个API,⽇常也会经常进⾏API的发布、升级、改造、下架等操作。对不同的服务,不同的访问者,需要提供不同的服务访问策略。有的商业API公司,还需要对API的使⽤进⾏付费。所以,与API⽹关配套的,需要⼀套完善的⾃助系统,提供给服务的提供者、管理者、使⽤者,来对服务的发布、使⽤、和运营。
业界常⽤的API⽹关⽅案
通常情况下, API ⽹关要做很多⼯作,它作为⼀个系统的后端总⼊⼝,承载着所有服务的组合路由转换等⼯作,除此之外,我们⼀般也会把安全,限流,缓存,⽇志,监控,重试,熔断等放到 API ⽹关来做,那么可以试想在⾼并发的情况下,这⾥可能会出现⼀个性能瓶颈。
另外,如果没有开源项⽬的⽀撑前提下,⾃⼰来做这样⼀套东西,是⾮常⼤的⼀个⼯作量,⽽且还要做 API ⽹关本⾝的⾼可⽤等,如果⼀旦做不好,有可能最先挂掉的不是你的其他服务,⽽就是这个API⽹关。
基于OpenResty 的 Nginx
性能和⾼可⽤性上
Nginx性能极⾼,Nginx先天的事件驱动型设计、全异步的⽹络I/O处理机制、极少的进程间切换以及许多优化设计,都使得Nginx 天⽣善于处理⾼并发压⼒下的互联⽹请求。Nginx的稳定性也在各⼤⽹站得到验证。官⽅提供的常⽤模块都⾮常稳定,每个worker 进程相对独⽴,master进程在1个worker进程出错时可以快速“拉起”新的worker⼦进程提供服务。⽀持热部署,可以不停机更新配置⽂件、更新⽇志⽂件、更新服务器程序版本。
扩展性上
Nginx的设计极具扩展性,它完全是由多个不同功能、不同层次、不同类型且耦合度极低的模块组成。因此,当对某⼀个模块修复Bug或进⾏升级时,可以专注于模块⾃⾝,⽆须在意其他
易⽤性上
Nginx使⽤最⾃由的BSD许可协议,允许⽤户在⾃⼰的项⽬中直接使⽤或修改Nginx源码,有⼤量的插件可以利⽤。但是,Nginx
Nginx使⽤最⾃由的BSD许可协议,允许⽤户在⾃⼰的项⽬中直接使⽤或修改Nginx源码,有⼤量的插件可以利⽤。但是,Nginx 模块需要⽤C开发,⽽且必须符合⼀系列复杂的规则。虽然通过第三⽅模块,可以⽀持Nginx与Perl、Lua等脚本语⾔集成⼯作,但对使⽤者的要求还是很⾼。
Spring Cloud Zuul
验证与安全保障: 识别⾯向各类资源的验证要求并拒绝那些与要求不符的请求。
审查与监控: 在边缘位置追踪有意义数据及统计结果,从⽽为我们带来准确的⽣产状态结论。
动态路由: 以动态⽅式根据需要将请求路由⾄不同后端集处。
压⼒测试: 逐渐增加指向集的负载流量,从⽽计算性能⽔平。
负载分配: 为每⼀种负载类型分配对应容量,并弃⽤超出限定值的请求。
静态响应处理: 在边缘位置直接建⽴部分响应,从⽽避免其流⼊内部集。
Netflix公司还利⽤Zuul的功能通过⾦丝雀版本实现精确路由与压⼒测试。虽然提供的功能还算丰富,但都⽐较弱,很难满⾜⾼要求的场景。
性能和⾼可⽤性
Zuul处理每个请求的⽅式是针对每个请求是⽤⼀个线程来处理。通常情况下,为了提⾼性能,所有请求会被放到处理队列中,从线程池中选取空闲线程来处理该请求。2016年底,Netflix将它们的⽹关服务Zuul进⾏了升级,全新的Zuul 2将HTTP请求的处理⽅式从同步变成了异步,以提升其处理性能。除了Netflix公司,⽬前Zuul在企业中⽤的还⽐较少,性能和稳定性⽅⾯还有待进⼀步观察。
扩展性上
从Zuul的架构图上可以看出,Zuul更像是⼀个过滤器框架,其⾃⾝的路由、⽇志、反向代理、ddos预防等功能都是通过过滤器实现的。提供了PRE、ROUTING、POST和ERROR四个扩展点,可以很容易的添加⾃定义的过滤器。
易⽤性上
Zuul的搭建⾮常简便,使⽤和配置也很简单。Zuul的开源社区⽐较活跃,⼀直在更新状态,但版本不算太稳定,在使⽤的过程中,还有⼀些坑要踩。例如重定向问题、异常处理问题,还没有解决的很好,需要⾃⼰重写⼀些filter。
Mashape Kong
Kong的⼀个⾮常诱⼈的地⽅就是提供了⼤量的插件来扩展应⽤,通过设置不同的插件可以为服务提供各种增强的功能。Kong默认插件插件包括:
⾝份认证:Kong提供了Basic Authentication、Key authentication、OAuth2.0 authentication、HMAC authentication、JWT、LDAP authentication认证实现。
安全:ACL(访问控制)、CORS(跨域资源共享)、动态SSL、IP限制、爬⾍检测实现。
流量控制:请求限流(基于请求计数限流)、上游响应限流(根据upstream响应计数限流)、请求⼤⼩限制。限流⽀持本地、Redis和集限流模式。
分析监控:Galileo(记录请求和响应数据,实现API分析)、Datadog(记录API Metric如请求次数、请求⼤⼩、响应状态和延迟,可视化API Metric)、Runscope(记录请求和响应数据,实现API性能测试和监控)。
转换:请求转换、响应转换
Kong本⾝也是基于Nginx的,所以在性能和稳定性上都没有问题。Kong作为⼀款商业软件,在Nginx上做了很扩展⼯作,⽽
且还有很多付费的商业插件。Kong本⾝也有付费的企业版,其中包括技术⽀持、使⽤培训服务以及 API 分析插件。
从对上⾯三种⽅案的⽐较中可以看到,Spring Cloud Zuul⾮常适合创业初期的团队,快速搭建⼀个“基本可⽤”的API⽹关。Nginx 适合有较强研发团队,⾃主开发企业⾃⼰的API⽹关。Kong适合于没有⾃⾝研发团队,但需要拥有企业级API⽹关能⼒的公司。
Orange:和Kong类似也是基于OpenResty的⼀个API⽹关程序,是由国⼈开发的。
apiaxle:Nodejs 实现的⼀个 API ⽹关。
api-umbrella:Ruby 实现的⼀个 API ⽹关。
Tyk:Tyk是⼀个开放源码的API⽹关,它是快速、可扩展和现代的。Tyk提供了⼀个API管理平台,其中包括API⽹关、API分析、开发⼈员门户和API管理⾯板。Try 是⼀个基于Go实现的⽹关服务。
⽐较:
Spring Cloud Zuul⾮常适合创业初期的团队,快速搭建⼀个“基本可⽤”的API⽹关。
OpenResty+Nginx适合有较强研发团队,⾃主开发企业⾃⼰的API⽹关。
spring到底是干啥的Kong适合于没有⾃⾝研发团队,但需要拥有企业级API⽹关能⼒的公司。
Try扩展需要会Go语⾔
但是上⾯的这些 API ⽹关都缺少超时,熔断,重试,聚合查询等功能。这个需要我们业务⾃⼰开发。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。