构建微服务:使用 API 网关

本文涉及的产品
服务治理 MSE Sentinel/OpenSergo,Agent数量 不受限
云原生网关 MSE Higress,422元/月
注册配置 MSE Nacos/ZooKeeper,118元/月
简介: 当您选择将应用程序构建为一组微服务时,您需要决定应用程序的客户端将如何与微服务交互。对于单体应用程序,只有一组(通常是复制的、负载平衡的)端点。然而,在微服务架构中,每个微服务都暴露了一组通常是细粒度的端点。在本文中,我们研究了这如何影响客户端到应用程序的通信,并提出了一种使用API 网关的方法。

当您选择将应用程序构建为一组微服务时,您需要决定应用程序的客户端将如何与微服务交互。对于单体应用程序,只有一组(通常是复制的、负载平衡的)端点。然而,在微服务架构中,每个微服务都暴露了一组通常是细粒度的端点。在本文中,我们研究了这如何影响客户端到应用程序的通信,并提出了一种使用API 网关的方法。

介绍

假设您正在为购物应用程序开发本机移动客户端。您可能需要实现一个产品详细信息页面,该页面显示任何给定产品的信息。

例如,下图显示了您在亚马逊的Android 移动应用程序中滚动浏览产品详细信息时看到的内容。

打开百度APP看高清图片

即使这是一个智能手机应用程序,产品详细信息页面也会显示大量信息。例如,不仅有基本的产品信息(如名称、描述和价格),而且此页面还显示:

  • 购物车中的商品数量
  • 订单历史
  • 顾客评论
  • 低库存警告
  • 送货选项
  • 各种推荐,包括经常购买该产品的其他产品,购买该产品的客户购买的其他产品,以及购买该产品的客户查看的其他产品
  • 替代购买选项

当使用单体应用程序架构时,移动客户端将通过对应用程序进行单个 REST 调用 ( ) 来检索此数据。负载均衡器将请求路由到 N 个相同的应用程序实例之一。然后应用程序查询各种数据库表并将响应返回给客户端。GET
api.company.com/productdetails/*productId*

相比之下,当使用微服务架构时,产品详情页面上显示的数据由多个微服务拥有。以下是示例产品详细信息页面上显示的拥有数据的一些潜在微服务:

  • 购物车服务 - 购物车中的商品数量
  • 订单服务 – 订单历史
  • 目录服务 - 基本产品信息,例如其名称、图像和价格
  • 评论服务 – 客户评论
  • 库存服务 - 低库存警告
  • 运输服务 – 运输选项、截止日期和费用,独立于运输提供商的 API
  • 推荐服务——推荐项目

我们需要决定移动客户端如何访问这些服务。让我们看看选项。

直接的客户端到微服务通信

理论上,客户端可以直接向每个微服务发出请求。每个微服务都有一个公共端点。该 URL 将映射到微服务的负载均衡器,该负载均衡器在可用实例之间分配请求。为了检索产品详细信息,移动客户端将向上面列出的每个服务发出请求。

不幸的是,此选项存在挑战和限制。一个问题是客户端的需求与每个微服务公开的细粒度 API 之间的不匹配。此示例中的客户端必须发出七个单独的请求。在更复杂的应用程序中,它可能需要做更多的事情。例如,亚马逊描述了数百种服务如何参与呈现他们的产品页面。虽然客户端可以通过 LAN 发出这么多请求,但在公共 Internet 上可能效率太低,而且在移动网络上肯定不切实际。这种方法还使客户端代码更加复杂。

客户端直接调用微服务的另一个问题是,有些可能使用不适合 Web 的协议。一项服务可能使用 Thrift 二进制 RPC,而另一项服务可能使用 AMQP 消息传递协议。这两种协议对浏览器或防火墙都不是特别友好,最好在内部使用。应用程序应在防火墙外使用 HTTP 和 WebSocket 等协议。

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

由于这些类型的问题,客户直接与微服务对话几乎没有意义。

使用 API 网关

通常更好的方法是使用所谓的API Gateway。API 网关是一个服务器,它是系统的单一入口点。它类似于面向对象设计的外观模式。API 网关封装了内部系统架构,并提供了为每个客户端量身定制的 API。它可能具有其他职责,例如身份验证、监控、负载平衡、缓存、请求整形和管理以及静态响应处理。

下图显示了 API 网关通常如何适应架构:

API 网关负责路由、组合和协议转换。来自客户端的所有请求首先通过 API 网关。然后它将请求路由到适当的微服务。API 网关通常会通过调用多个微服务并聚合结果来处理请求。它可以在 HTTP 和 WebSocket 等 Web 协议与内部使用的 Web 不友好协议之间进行转换。

API 网关还可以为每个客户端提供自定义 API。它通常为移动客户端公开一个粗粒度的 API。例如,考虑产品详细信息场景。API 网关可以提供一个端点,使移动客户端能够通过单个请求检索所有产品详细信息。API 网关通过调用各种服务(产品信息、推荐、评论等)并组合结果来处理请求。

API 网关的一个很好的例子是Netflix API 网关。Netflix 流媒体服务可在数百种不同类型的设备上使用,包括电视、机顶盒、智能手机、游戏系统、平板电脑等。最初,Netflix 试图为其流媒体服务提供一刀切的API。然而,他们发现由于设备种类繁多及其独特的需求,它并不能很好地工作。今天,他们使用 API 网关,通过运行特定于设备的适配器代码为每个设备提供定制的 API。适配器通常通过平均调用六到七个后端服务来处理每个请求。Netflix API 网关每天处理数十亿个请求。

API 网关的优点和缺点

正如您所料,使用 API 网关既有优点也有缺点。使用 API 网关的一个主要好处是它封装了应用程序的内部结构。客户端无需调用特定服务,只需与网关对话即可。API 网关为每种客户端提供特定的 API。这减少了客户端和应用程序之间的往返次数。它还简化了客户端代码。

API 网关也有一些缺点。它是另一个必须开发、部署和管理的高可用性组件。API 网关也存在成为开发瓶颈的风险。开发人员必须更新 API 网关才能公开每个微服务的端点。更新 API 网关的过程尽可能轻量级很重要。否则,开发者将被迫排队等待更新网关。然而,尽管有这些缺点,但对于大多数实际应用程序来说,使用 API 网关是有意义的。

实现 API 网关

既然我们已经了解了使用 API 网关的动机和权衡取舍,那么让我们看看您需要考虑的各种设计问题。

性能和可扩展性

只有少数公司以 Netflix 的规模运营,每天需要处理数十亿个请求。但是,对于大多数应用程序而言,API 网关的性能和可扩展性通常非常重要。因此,在支持异步、非阻塞 I/O 的平台上构建 API 网关是有意义的。有多种不同的技术可用于实现可扩展的 API 网关。在 JVM 上,您可以使用基于 NIO 的框架之一,例如 Netty、Vertx、Spring Reactor 或 JBoss Undertow。一个流行的非 JVM 选项是 Node.js,它是一个基于 Chrome 的 JavaScript 引擎构建的平台。另一种选择是使用NGINX Plus, NGINX Plus 提供成熟、可扩展、高性能的 Web 服务器和反向代理,易于部署、配置和编程。NGINX Plus 可以管理身份验证、访问控制、负载平衡请求、缓存响应,并提供应用程序感知的健康检查和监控。

使用反应式编程模型

API 网关通过简略地将它们路由到恰当的后端服务来处理一些请求。它通过调用多个后端服务并聚合结果来处理其他请求。对于某些清求,例如产品详细信息请求,对后端服务的请求是相互独立的。为了最小化响应时间,API 网关应当同时履行独立的请求。但是,有时清求之间存在依赖关联。API 网关可能首先需要通过调用身份验证服务来验证恳求,然后再将恳求路由到后端服务。同样,如果获得有关客户愿望清单中产品的信息,API 网关必须首先检索包含该信息的客户配置文件,然后检索每个产品的信息。

使用传统的异步回调方法编写 API 组合代码会很快将您带入回调地狱。代码会很纠结,难以理解,而且容易出错。更好的方法是使用响应式方法以声明式风格编写 API Gateway 代码。响应式抽象的示例包括Scala 中的Future、Java 8 中的[CompletableFuture和 JavaScript 中的Promise。还有反应式扩展(也称为 Rx 或 ReactiveX),最初由 Microsoft 为 .NET 平台开发。Netflix 为 JVM 创建了 RxJava,专门用于他们的 API 网关。还有用于 JavaScript 的 RxJS,它可以在浏览器和 Node.js 中运行。使用反应式方法将使您能够编写简单而高效的 API 网关代码。

服务调用

基于微服务的应用程序是一个分布式系统,必须使用进程间通信机制。进程间通信有两种风格。一种选择是使用基于消息传递的异步机制。一些实现使用消息代理,例如 JMS 或 AMQP。其他的,例如 Zeromq,是无代理的,服务直接通信。另一种进程间通信方式是同步机制,例如 HTTP 或 Thrift。系统通常会同时使用异步和同步样式。它甚至可能使用每种样式的多个实现。因此,API 网关需要支持多种通信机制。

服务发现

API 网关需要晓得与之通信的每个微服务的位置(IP 地点和端口)。在传统应用程序中,您可能可以硬连接位置,但在现代、基于云的微服务应用程序中,这是一个不平常的难题。基础设施服务,例如消息代理,通常有一个静态位置,可以通过操作系统环境变量指定。然而,确定应用服务的位置并不容易。应用程序服务具备动态分配的位置。此外,由于自动缩放和升级,服务的实例会议动态变化。因此,API 网关与体系中的任何其他服务客户端一样,需要应用体系的服务发现机制:服务器端发现或客户端发现。现在,值得注意的是,如果系统应用客户端发现,那么 API 网关必须能够查询服务注册表,这是一个包含所有微服务实例及其位置的数据库。

处理部分故障

实现 API 网关时必须解决的另一个问题是部分失败的问题。每当一个服务调用另一个响应缓慢或不可用的服务时,所有分布式系统都会出现此问题。API 网关不应该无限期地

实现 API 网关时必须解决的另一个题目是局部失败的问题。每当一个服务调用另一个响应迟缓或不可用的服务时,所有分布式体系城市出现此问题。API 网关不应当无限期地阻塞等待下游服务。但是,它如何处理失败取决于具体的场景和失败的服务。例如,如果推举服务在产品详情场景中没有响应,API 网关应当将其余的产品详情返回给客户端,因为它们对用户仍然有效。这些提议可以是空的,也可以由例如硬连线的前十名列表调换。但是,如果产品信息服务没有响应,那么 API Gateway 该当向客户端返回一个错误。

如果可用,API 网关也可以返回缓存数据。例如,由于产品价钱不经常变化,如果定价服务不可用,API 网关可能会返回缓存的定价数据。数据可以由 API Gateway 本身缓存,也可以存储在 Redis 或 Memcached 等外部缓存中。通过返回默认数据或缓存数据,API Gateway 确保体系故障不会影响用户体验。

Netflix Hystrix是一个非常有用的库,用于编写调用远程服务的代码。Hystrix 超时调用超过指定阈值。它实现了一个断路器模式,阻止客户端不必要地等待无响应的服务。如果服务的错误率超过指定的阈值,Hystrix 会触发断路器,并且所有请求将在指定的时间段内立即失败。Hystrix 允许您在请求失败时定义回退操作,例如从缓存中读取或返回默认值。如果您使用的是 JVM,则绝对应该考虑使用 Hystrix。而且,如果您在非 JVM 环境中运行,则应该使用等效的库。

概括

对于大多数基于微服务的应用程序,实现 API 网关是有意义的,它充当系统的单个入口点。API 网关负责请求路由、组合和协议转换。它为每个应用程序的客户端提供自定义 API。API 网关还可以通过返回缓存或默认数据来屏蔽后端服务中的故障。


目录
相关文章
|
3天前
|
运维 Cloud Native 应用服务中间件
阿里云微服务引擎 MSE 及 云原生 API 网关 2024 年 11 月产品动态
阿里云微服务引擎 MSE 面向业界主流开源微服务项目, 提供注册配置中心和分布式协调(原生支持 Nacos/ZooKeeper/Eureka )、云原生网关(原生支持Higress/Nginx/Envoy,遵循Ingress标准)、微服务治理(原生支持 Spring Cloud/Dubbo/Sentinel,遵循 OpenSergo 服务治理规范)能力。API 网关 (API Gateway),提供 APl 托管服务,覆盖设计、开发、测试、发布、售卖、运维监测、安全管控、下线等 API 生命周期阶段。帮助您快速构建以 API 为核心的系统架构.满足新技术引入、系统集成、业务中台等诸多场景需要
|
9天前
|
JSON JavaScript 前端开发
深入浅出Node.js:从零开始构建RESTful API
在数字化时代的浪潮中,后端开发作为连接用户与数据的桥梁,扮演着至关重要的角色。本文将引导您步入Node.js的奇妙世界,通过实践操作,掌握如何使用这一强大的JavaScript运行时环境构建高效、可扩展的RESTful API。我们将一同探索Express框架的使用,学习如何设计API端点,处理数据请求,并实现身份验证机制,最终部署我们的成果到云服务器上。无论您是初学者还是有一定基础的开发者,这篇文章都将为您打开一扇通往后端开发深层知识的大门。
26 12
|
2天前
|
Cloud Native API 微服务
微服务引擎 MSE 及云原生 API 网关 2024 年 11 月产品动态
微服务引擎 MSE 及云原生 API 网关 2024 年 11 月产品动态。
|
12天前
|
弹性计算 持续交付 API
构建高效后端服务:微服务架构的深度解析与实践
在当今快速发展的软件行业中,构建高效、可扩展且易于维护的后端服务是每个技术团队的追求。本文将深入探讨微服务架构的核心概念、设计原则及其在实际项目中的应用,通过具体案例分析,展示如何利用微服务架构解决传统单体应用面临的挑战,提升系统的灵活性和响应速度。我们将从微服务的拆分策略、通信机制、服务发现、配置管理、以及持续集成/持续部署(CI/CD)等方面进行全面剖析,旨在为读者提供一套实用的微服务实施指南。
|
8天前
|
设计模式 负载均衡 监控
探索微服务架构下的API网关设计
在微服务的大潮中,API网关如同一座桥梁,连接着服务的提供者与消费者。本文将深入探讨API网关的核心功能、设计原则及实现策略,旨在为读者揭示如何构建一个高效、可靠的API网关。通过分析API网关在微服务架构中的作用和挑战,我们将了解到,一个优秀的API网关不仅要处理服务路由、负载均衡、认证授权等基础问题,还需考虑如何提升系统的可扩展性、安全性和可维护性。文章最后将提供实用的代码示例,帮助读者更好地理解和应用API网关的设计概念。
36 8
|
11天前
|
负载均衡 Java 开发者
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
深入探索Spring Cloud与Spring Boot:构建微服务架构的实践经验
44 5
|
8天前
|
监控 安全 持续交付
构建高效微服务架构:策略与实践####
在数字化转型的浪潮中,微服务架构凭借其高度解耦、灵活扩展和易于维护的特点,成为现代企业应用开发的首选。本文深入探讨了构建高效微服务架构的关键策略与实战经验,从服务拆分的艺术到通信机制的选择,再到容器化部署与持续集成/持续部署(CI/CD)的实践,旨在为开发者提供一套全面的微服务设计与实现指南。通过具体案例分析,揭示如何避免常见陷阱,优化系统性能,确保系统的高可用性与可扩展性,助力企业在复杂多变的市场环境中保持竞争力。 ####
26 2
|
9天前
|
弹性计算 Kubernetes API
构建高效后端服务:微服务架构的深度剖析与实践####
本文深入探讨了微服务架构的核心理念、设计原则及实现策略,旨在为开发者提供一套系统化的方法论,助力其构建灵活、可扩展且易于维护的后端服务体系。通过案例分析与实战经验分享,揭示了微服务在提升开发效率、优化资源利用及增强系统稳定性方面的关键作用。文章首先概述了微服务架构的基本概念,随后详细阐述了其在后端开发中的应用优势与面临的挑战,最后结合具体实例,展示了如何从零开始规划并实施一个基于微服务的后端项目。 ####
|
13天前
|
消息中间件 监控 安全
构建高效微服务架构:最佳实践与挑战
在现代软件开发中,微服务架构因其高度的可扩展性、灵活性和敏捷性而受到青睐。本文深入探讨了构建高效微服务架构的关键策略,包括服务的划分、通信机制、数据管理、部署与监控等方面的最佳实践。同时,文章也分析了在实施过程中可能遇到的挑战,如服务间的依赖管理、数据一致性问题、安全考量及性能优化等,并提出了相应的解决方案。通过实际案例分析,本文旨在为开发者提供一套实用的指南,帮助他们在构建微服务系统时能够有效规避风险,提升系统的健壮性和用户体验。
|
26天前
|
缓存 负载均衡 JavaScript
探索微服务架构下的API网关模式
【10月更文挑战第37天】在微服务架构的海洋中,API网关犹如一座灯塔,指引着服务的航向。它不仅是客户端请求的集散地,更是后端微服务的守门人。本文将深入探讨API网关的设计哲学、核心功能以及它在微服务生态中扮演的角色,同时通过实际代码示例,揭示如何实现一个高效、可靠的API网关。