使用 API 网关构建微服务

本期内容

微服务系列文章的第一篇介绍了微服务架构模式,讨论了使用微服务的优缺点,以及为什么微服务虽然复杂度高却是复杂应用程序的理想选择。

在决定以一组微服务来构建自己的应用时,你需要确定应用客户端如何与微服务交互。

在单体式程序中,通常只有一组冗余的或者负载均衡的服务提供点。在微服务架构中,每一个微服务暴露一组细粒度的服务提供点。在本篇文章中,我们来看它如何影响客户端到服务端通信,并提出一种使用 API 网关的方法。

简要概述

让我们想象一下,你要为一个购物应用程序开发一个原生移动客户端。你很可能需要实现一个产品详情页面,展示任何指定商品的信息。

下图展示了 Amazon Android 应用在商品详情页显示的内容。

Richardson-microservices-part2-1_amazon-apps

 

即使只是个智能手机应用,产品详情页面也显示了大量的信息。该页面不仅包含基本的产品信息(如名称、描述、价格),而且还显示了如下内容:

  • 购物车中的商品数量
  • 历史订单
  • 客户评论
  • 低库存预警
  • 送货选项
  • 各种推荐,包括经常与该商品一起购买的其它商品、购买该商品的客户购买的其它商品、购买该商品的客户看过的其它商品
  • 其它的购物选择

使用单体应用程序架构时,移动客户端通过向应用程序发起一次 REST 调用(GET api.company.com/productdetails/)来获取这些数据。负载均衡器将请求路由给 N 个相同的应用程序实例中的其中之一。然后,应用程序会查询各种数据库表,并将响应返回给客户端。

相反,若是采用微服务架构,显示在产品页上的数据会分布在不同的微服务上。下面列举了可能与产品详情页数据有关的一些微服务:

  • 购物车服务——购物车中的件数
  • 订单服务——历史订单
  • 目录服务——商品基本信息,如名称、图片和价格
  • 评论服务——客户的评论
  • 库存服务——低库存预警
  • 送货服务——送货选项、期限和费用,这些信息单独从送货方 API 获取
  • 推荐服务——推荐商品

Richardson-microservices-part2-2_microservices-client

我们需要决定移动客户端如何访问这些服务。让我们看看有哪些方法。

客户端与微服务直接通信

从理论上讲,客户端可以直接向每个微服务发送请求。每个微服务都有一个公开的端点(https ://.api.company.name)。该 URL 映射到微服务的负载均衡器,由后者负责在可用实例之间分发请求。为了获取产品详情,移动客户端将逐一向上文列出的 N 个服务发送请求。

遗憾的是,这种方法存在挑战和局限。问题之一是客户端需求和每个微服务暴露的细粒度 API 不匹配。在这个例子中,客户端需要发送 7 个独立请求。在更复杂的应用程序中,可能要发送更多的请求;按照 Amazon 的说法,他们在显示他们的产品页面时就调用了数百个服务。然而,客户端通过 LAN 发送许多请求,这在公网上可能会很低效,在移动网络上就根本不可行。这种方法还使得客户端代码非常复杂。

客户端直接调用微服务的另一个问题是,部分服务使用的协议对 web 并不友好。一个服务可能使用 Thrift 二进制 RPC,而另一个服务可能使用 AMQP 消息传递协议。不管哪种协议对于浏览器或防火墙都不够友好,最好是内部使用。在防火墙之外,应用程序应该使用诸如 HTTP 和 WebSocket 之类的协议。

这种方法的另一个缺点是,它会使得微服务难以重构。随着时间推移,我们可能想要更改系统拆分成服务的方式。例如,我们可能合并两个服务,或者将一个服务拆分成两个或更多服务。然而,如果客户端与微服务直接通信,那么执行这类重构就非常困难了。

由于上述三种问题的原因,客户端直接与服务器端通信的方式很少在实际中使用。

使用 API 网关构建微服务

通常来说,使用 API 网关是更好的解决方式。API 网关是一个服务器,也可以说是进入系统的唯一节点。这与面向对象设计模式中的 Facade 模式很像。API 网关封装内部系统的架构,并且提供 API 给各个客户端。它还可能还具备授权、监控、负载均衡、缓存、请求分片和管理、静态响应处理等功能。下图展示了一个适应当前架构的 API 网关。

Richardson-microservices-part2-3_api-gateway

API 网关负责服务请求路由、组合及协议转换。客户端的所有请求都首先经过 API 网关,然后由它将请求路由到合适的微服务。API 网关经常会通过调用多个微服务并合并结果来处理一个请求。它可以在 web 协议(如 HTTP 与 WebSocket)与内部使用的非 web 友好协议之间转换。

API 网关还能为每个客户端提供一个定制的 API。通常,它会向移动客户端暴露一个粗粒度的 API。以产品详情的场景为例,API 网关可以提供一个端点(/productdetails?productid=xxx),使移动客户端可以通过一个请求获取所有的产品详情。API 网关通过调用各个服务(产品信息、推荐、评论等等)并合并结果来处理请求。

Netflix API 网关是一个很好的 API 网关实例。Netflix 流媒体服务提供给成百上千种类型的设备使用,包括电视、机顶盒、智能手机、游戏系统、平板电脑等等。

最初,Netflix 试图为他们的流媒体服务提供一个通用的 API。然而他们发现,由于各种各样的设备都有自己独特的需求,这种方式并不能很好地工作。如今,他们使用一个 API 网关,通过运行与针对特定设备的适配器代码,来为每种设备提供定制的 API。通常,一个适配器通过调用平均 6 到 7 个后端服务来处理每个请求。Netflix API 网关每天处理数十亿请求。

API 网关的优点和缺点

如你所料,使用 API 网关有优点也有不足。使用 API 网关的最大优点是,它封装了应用程序的内部结构。客户端只需要同网关交互,而不必调用特定的服务。API 网关为每一类客户端提供了特定的 API,这减少了客户端与应用程序间的交互次数,还简化了客户端代码。

API 网关也有一些不足。它增加了一个我们必须开发、部署和维护的高可用组件。还有一个风险是,API 网关变成了开发瓶颈。为了暴露每个微服务的端点,开发人员必须更新 API 网关。API网关的更新过程要尽可能地简单,这很重要;否则,为了更新网关,开发人员将不得不排队等待。不过,虽然有这些不足,但对于大多数现实世界的应用程序而言,使用 API 网关是合理的。

资源下载链接为: https://pan.quark.cn/s/3d8e22c21839 随着 Web UI 框架(如 EasyUI、JqueryUI、Ext、DWZ 等)的不断发展与成熟,系统界面的统一化设计逐渐成为可能,同时代码生成器也能够生成符合统一规范的界面。在这种背景下,“代码生成 + 手工合并”的半智能开发模式正逐渐成为新的开发趋势。通过代码生成器,单表数据模型以及一对多数据模型的增删改查功能可以被直接生成并投入使用,这能够有效节省大约 80% 的开发工作量,从而显著提升开发效率。 JEECG(J2EE Code Generation)是一款基于代码生成器的智能开发平台。它引领了一种全新的开发模式,即从在线编码(Online Coding)到代码生成器生成代码,再到手工合并(Merge)的智能开发流程。该平台能够帮助开发者解决 Java 项目中大约 90% 的重复性工作,让开发者可以将更多的精力集中在业务逻辑的实现上。它不仅能够快速提高开发效率,帮助公司节省大量的人力成本,同时也保持了开发的灵活性。 JEECG 的核心宗旨是:对于简单的功能,可以通过在线编码配置来实现;对于复杂的功能,则利用代码生成器生成代码后,再进行手工合并;对于复杂的流程业务,采用表单自定义的方式进行处理,而业务流程则通过工作流来实现,并且可以扩展出任务接口,供开发者编写具体的业务逻辑。通过这种方式,JEECG 实现了流程任务节点和任务接口的灵活配置,既保证了开发的高效性,又兼顾了项目的灵活性和可扩展性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值