API Gateway,它是微服务系统的单一入口点。它类似于面向对象设计中的Facade模式。API Gateway封装了内部系统体系结构,并提供了适合每个客户端的API。它可能具有其他职责,如身份验证、监视、负载平衡、缓存、请求形成和管理以及静态响应处理。
使用API Gateway的好处是:
- 它封装了应用程序的内部结构。客户端不需要调用特定的服务,只需与网关通信即可。
- API Gateway为每种客户端提供特定的API。这减少了客户端和应用程序之间的往返次数.
- 简化了客户端代码。
API Gateway也有一些缺点。 - 它是另一个必须开发、部署和管理的高可用性组件。
- API Gateway也有成为开发瓶颈的风险。
- 开发人员必须更新API Gateway,以便公开每个微服务的端点。重要的是,更新API Gateway的过程要尽可能轻量级。否则,开发人员将被迫排队等待更新网关。
所以, 我们在设计API Gateway的时候,需要注意的设计原则是:
- 性能和可扩展性
对于大多数应用程序来说,API Gateway的性能和可扩展性通常非常重要. 一个好的API Gateway可以实现每天处理数十亿的请求.
在构建API Gateway的时候, 我们可以考虑支持异步和NIO. 实现技术主要包括:
在JVM中,可以使用Netty, Spring Reactor.
也可以基于Node.js来实现, 还有一个比较好的组件是NGINX Plus, 它提供了一个成熟的、可伸缩的、高性能的web服务器和反向代理,易于部署、配置和编程。NGINX Plus可以管理身份验证、访问控制、负载平衡请求、缓存响应,并提供应用程序感知的健康检查和监视。
- 基于响应式程序设计
API Gateway通过简单地将一些请求路由到适当的后端服务来处理这些请求。它通过调用多个后端服务并聚合结果来处理其他请求。对于某些请求,例如产品详细信息请求,对后端服务的请求彼此独立。为了最小化响应时间,API Gateway应该并发地执行独立请求。然而,有时请求之间存在依赖关系。在将请求路由到后端服务之前,API Gateway可能首先需要通过调用身份验证服务来验证请求.
使用传统的异步回调方法编写API组合代码会很快导致回调地狱。代码将是混乱的,难以理解,容易出错。更好的方法是使用响应式的程序设计, 例如 Scala中的Future, Java 8中的CompletableFuture和JavaScript中的Promise.Netflix为JVM创建了专门用于其API Gateway的RxJava.
使用响应式的程序,可以写出简单高效的API Gateway代码.
- 服务之间的调用
基于微服务的应用程序是一个分布式系统,必须使用进程间通信机制。进程间通信有两种类型。一种选择是使用基于消息传递的异步机制。有些实现使用消息代理,如JMS或AMQP。其他的,如Zeromq,是没有代理的,服务直接通信。进程间通信的另一种形式是同步机制,如HTTP或Thrift。系统通常同时使用异步和同步样式。它甚至可能使用每种样式的多个实现。因此,API Gateway将需要支持各种通信机制。
- 服务发现
API Gateway需要知道与之通信的每个微服务的位置(IP地址和端口)。然而,确定应用程序服务的位置并不那么容易。应用程序服务动态地分配了位置。此外,由于自动缩放和升级,服务的一组实例会动态更改。因此,与系统中的任何其他服务客户端一样,API Gateway需要使用系统的服务发现机制:服务器端发现或客户端发现。如果系统使用客户端发现,那么API Gateway必须能够查询服务注册表,它是所有微服务实例及其位置的数据库。
- 失败的处理
实现API Gateway时必须解决的另一个问题是部分服务调用失败的处理。当一个服务调用另一个响应缓慢或不可用的服务时,在所有分布式系统中都会出现这个问题。API Gateway不应该无限期地阻塞等待下游服务。但是,它如何处理失败取决于特定的场景和哪个服务正在失败。例如,如果推荐服务在产品详细信息场景中没有响应,API Gateway应该将剩余的产品详细信息返回给客户端,因为它们仍然对用户有用。
数据可以由API Gateway本身缓存,也可以存储在诸如Redis或Memcached之类的外部缓存中。通过返回默认数据或缓存数据,API Gateway确保系统故障不会影响用户体验。
Netflix Hystrix是一个非常有用的库,用于编写调用远程服务的代码。Hystrix超时超过指定阈值的调用。它实现了一种断路器模式,可以阻止客户端不必要地等待没有响应的服务。如果服务的错误率超过指定的阈值,Hystrix将跳闸断路器,所有请求将在指定的时间内立即失败。Hystrix允许您在请求失败时定义回退操作,例如从缓存读取数据或返回默认值。如果你正在使用JVM,可以考虑使用Hystrix.
下面是一个Netflix的微服务实践架构图: