【编者的话】本系列的第一篇介绍了微处事架构模式。它讨论了给与微处事的长处和错误谬误,除了一些庞大的微处事,这种模式还是庞大应用的抱负选择。
当你决定将应用作为一组微处事时,需要决定应用客户端如何与微处事交互。在单体式措施中,凡是只有一组冗余的或者负载均衡的处事供给点。在微处事架构中,每一个微处事袒露一组细粒度的处事供给点。在本篇文章中,我们来看它如何影响客户端随处事端通信,同时提出一种API Gateway的要领。
介绍
假定你正在为在线购物应用开发一个原生手机客户端。你需要实现一个产品最终页来展示商品信息。
例如,下面的图展示了你在亚马逊Android客户端上滑动产品最终页时看到的信息。
虽然这是一个智能手机应用,这个产品最终页展示了非常多的信息。例如,不只这里有产品根基信息(名字、描述和价格),还有以下内容:
购物车中的物品数
下单历史
用户评论
低库存警告
快递选项
各样百般的保举,包孕经常跟这个物品一起被采办的产品、采办该物品的其他顾客采办的产品以及采办该产品的顾客还浏览了哪些产品。
可选的购物选项
当给与一个单体式应用架构,一个移动客户端将会通过一个REST请求(GET api.company.com/productdetails/productId)来获取这些数据。一个负载均衡将请求分发到多个应用实例之一。应用将盘问各类数据库并返回请求给客户端。
相对的,若是给与微处事架构,最终页上的数据会漫衍在差此外微处事上。下面列举了可能与产品最终页数据有关的一些微处事:
购物车处事 -- 购物车中的物品数
下单处事 -- 下单历史
分类处事 -- 根基产品信息,如名字、图片和价格
评论处事 -- 用户评论
库存处事 -- 低库存警告
快递处事 -- 快递选项、截止时间、来自差别快递API的本钱计算
保举处事 -- 保举产品
我们需要决定移动客户端如何访谒这些处事。请看下面这几种方法
客户端到微处事直接通信 理论上说,一个客户端可以直接给多个微处事中的任何一个倡议请求。每一个微处事城市有一个对外处事端(https://serviceName.api.company.name)。这个URL可能会映射到微处事的负载均衡上,它再转发请求到具体节点上。为了搜索产品细节,移动端需要向上述微处事逐个发请求。
不幸的是,这个方案有很多困难和限制。此中一个问题是客户真个需求量与每个微处事袒露的细粒度API数量的不匹配。如图中,客户端需要7次单独请求。在更庞大的场景中,可能会需要更多次请求。例如,亚马逊的产品最终页要请求数百个微处事。虽然一个客户端可以通过LAN倡议很多个请求,但是在公网上这样会很没有效率,这个问题在移动互联网上尤为突出。这个方案同时会导致客户端代码非常庞大。
另一个存在的问题是客户端直接请求微处事的协议可能并不是web友好型。一个处事可能是用Thrift的RPC协议,而另一个处事可能是用AMQP动静协议。它们都不是浏览或防火墙友好的,并且最好是内部使用。应用应该在防火墙外给与类似HTTP或者WEBSocket协议。
这个方案的另一个错误谬误是它很难重构微处事。跟着时间的推移,我们可能需要转变系统微处事目前的切分方案。例如,我们可能需要将两个处事合并或者将一个处事拆分为多个。但是,如果客户端直接与微处事交互,那么这种重构就很难实施。
由于上述三种问题的原因,客户端直接与处事器端通信的方法很少在实际中使用。
给与一个API Gateway 凡是来说,一个更好的解决步伐是给与API Gateway的方法。API Gateway是一个处事器,也可以说是进入系统的独一节点。这跟面向东西设计模式中的Facade模式很像。API Gateway封装内部系统的架构,并且供给API给各个客户端。它还可能有其他成果,如授权、监控、负载均衡、缓存、请求分片和打点、静态响应措置惩罚惩罚等。下图展示了一个适该当前架构的API Gateway。
API Gateway卖力请求转发、合成和协议转换。所有来自客户真个请求都要先颠末API Gateway,然后路由这些请求到对应的微处事。API Gateway将经常通过挪用多个微处事来措置惩罚惩罚一个请求以及聚合多个处事的功效。它可以在web协议与内部使用的非Web友好型协议间进行转换,如HTTP协议、WebSocket协议。
API Gateway可以供给给客户端一个定制化的API。它袒露一个粗粒度API给移动客户端。以产品最终页这个使用场景为例。API Gateway供给一个处事供给点(/productdetails?productid=xxx)使得移动客户端可以在一个请求中检索到产品最终页的全部数据。API Gateway通过挪用多个处事来措置惩罚惩罚这一个请求并返回功效,涉及产品信息、保举、评论等。
一个很好的API Gateway例子是Netfix API Gateway。Netflix流处事供给数百个差此外微处事,包孕电视、机顶盒、智能手机、游戏系统、平板电脑等。起初,Netflix视图供给一个适用全场景的API。但是,他们发明这种形式欠好用,因为涉及到各样百般的设备以及它们奇特的需求。此刻,他们给与一个API Gateway来供给容错性高的API,针对差别类型设备有相应代码。事实上,一个适配器措置惩罚惩罚一个请求平均要挪用6到8个后端处事。Netflix API Gateway每天措置惩罚惩罚数十亿的请求。
API Gateway的长处和错误谬误 如你所料,给与API Gateway也是优错误谬误并存的。API Gateway的一个最大好处是封装应用内部布局。对比起来挪用指定的处事,客户端直接跟gatway交互更简单点。API Gateway供给给每一个客户端一个特定API,这样减少了客户端与处事器真个通信次数,也简化了客户端代码。
API Gateway也有一些错误谬误。它是一个高可用的组件,必需要开发、部署和打点。还有一个问题,它可能成为开发的一个瓶颈。开发者必需更新API Gateway来供给新处事供给点来撑持新袒露的微处事。更新API Gateway时必需越轻量级越好。否则,开发者将因为更新Gateway而排行列队伍。但是,除了这些错误谬误,对付大部分的应用,给与API Gateway的方法都是有效的。
实现一个API Gateway 既然我们已经知道了给与API Gateway的动机和优错误谬误,下面来看在设计它时需要考虑哪些工作。
性能和可扩展性 只有少数公司需要措置惩罚惩罚像Netflix那样的规模,每天需要措置惩罚惩罚数十亿的请求。但是,对付大大都应用,API Gateway的性能和可扩展性也长短常重要的。因此,创建一个撑持同步、非梗阻I/O的API Gateway是有意义的。已经有差此外技术可以用来实现一个可扩展的API Gateway。在JVM上,给与基于NIO技术的框架,如Netty,Vertx,Spring Reactor或者JBoss Undertow。Node.js是一个非JVM的风行平台,它是一个在Chrome的JavaScript引擎根本上成立的平台。一个可选的方案是NGINX Plus。NGINX Plus供给一个成熟的、可扩展的、高性能web处事器和反向代办代理,它们均容易部署、配置和二次开发。NGINX Plus可以打点授权、权限控制、负载均衡、缓存并供给应用健康查抄和监控。
给与反响性编程模型 对付有些请求,API Gateway可以通过直接路由请求到对应的后端处事上的方法来措置惩罚惩罚。对付此外一些请求,它需要挪用多个后端处事并合并功效来措置惩罚惩罚。对付一些请求,例如产品最终页面请求,发给后端处事的请求是彼此独立的。为了最小化响应时间,API Gateway应该并发的措置惩罚惩罚彼此独立的请求。但是,有时候请求之间是有依赖的。API Gateway可能需要先通过授权处事来验证请求,然后在路由到后端处事。类似的,为了获得客户的产品愿望清单,需要先获取该用户的资料,然后返回清单上产品的信息。这样的一个API 组件是Netflix Video Grid。
操作传统的同步回调要领来实现API合并的代码会使得你进入回调函数的恶梦中。这种代码将非常难度且难以维护。一个优雅的解决方案是给与反响性编程模式来实现。类似的反响抽象实现有Scala的Future,Java8的CompletableFuture和JavaScript的。基于微软.Net平台的有Reactive Extensions(Rx)。Netflix为JVM环境创建了RxJava来使用他们的API Gateway。同样地,JavaScript平台有RxJS,可以在浏览器和Node.js平台上运行。给与反响编程要领可以辅佐快速实现一个高效的API Gateway代码。
处事挪用 一个基于微处事的应用是一个漫衍式系统,并且必需给与线程间通信的机制。有两种线程间通信的要领。一种是给与异步机制,基于动静的要领。这类的实现要领有JMS和AMQP。此外的,例如Zeromq属于处事间直接通信。还有一种线程间通信给与同步机制,例如Thrift和HTTP。事实上一个系统会同时给与同步和异步两种机制。由于它的实现方法有很多种,因此API Gateway就需要撑持多种通信方法。
处事发明 API Gateway需要知道每一个微处事的IP和端口。在传统应用中,你可能会硬编码这些地点,但是在此刻云根本的微处事应用中,这将是个简单的问题。根本处事凡是会给与静态地点,可以给与操纵系统环境变量来指定。但是,探测应用处事的地点就没那么容易了。应用处事凡是动态分配地点和端口。同样的,由于扩展或者升级,处事的实例也会动态的转变。因此,API Gateway需要给与系统的处事发明机制,要么给与处事端发明,要么是客户端发明。后续的一篇文章将会更详细的介绍这部分。如果给与客户端发明处事,API Gateway必需要去盘问处事注册处,也就是微处事实例地点的数据库。
措置惩罚惩罚部分掉败 在实现API Gateway过程中,此外一个需要考虑的问题就是部分掉败。这个问题产生在漫衍式系统中当一个处事挪用此外一个处事超时或者不成用的情况。API Gateway不应该被阻断并处于无限期期待下游处事的状态。但是,如何措置惩罚惩罚这种掉败依赖于特定的场景和具体处事。例如,如果是在产品详情页的保举处事模块无响应,那么API Gateway应该返回剩下的其他信息给用户,因为这些信息也是有用的。保举部分可以返回空,也可以返回固定的顶部10个给用户。但是,如果是产品信息处事无响应,那么API Gateway就应该给客户端返回一个错误。
在缓存有效的时候,API Gateway应该能够返回缓存。例如,由于产品价格变革并不频繁,API Gateway在价格处事不成用时应该返回缓存中的数值。这类数据可以由API Gateway自身来缓存,也可以由Redis或Memcached这类外部缓存实现。通过返回缓存数据或者默认数据,API Gateway来确保系统错误不影响到用户体验。
Netflix Hystrix对付实现长途处事挪用代码来说是一个非常好用的库。Hystrix记录那些赶过预设定的极限值的挪用。它实现了circuit break模式,使得可以将客户端从无响应处事的无尽期待中遏制。如果一个处事的错误率赶过预设值,Hystrix将中断处事,并且在一段时间内所有请求立刻掉效。Hystrix可以为请求掉败界说一个fallback操纵,例如读取缓存或者返回默认值。如果你在用JVM,就应该考虑使用Hystrix。如果你给与的非JVM环境,那么应该考虑给与类似成果的库。
总结 对付大大都微处事根本的应用,实现一个API Gateway都是有意义的,,它就像是进入系统的一个处事供给点。API Gateway卖力请求转发、请求合成和协议转换。它供给给应用客户端一个自界说的API。API Gateway可以通过返回缓存或者默认值的方法来掩盖后端处事的错误。在本系列的下一篇文章中,我们将讨论处事间的通信问题。
原文链接:Building Microservices: Using an API Gateway (翻译:陈杰;审校:杨峰)
===============================================