Apollo Federation 子图之间的服务间通信

Pet*_*ota 9 node.js apollo google-kubernetes-engine graphql apollo-federation

假设我们有S1S2子图和G网关。

S1子图服务需要来自服务的一些数据S2。应该如何通过网关和模式级别进行处理?在这种通信中我们应该使用网关吗?

我们是否应该在包含内部查询和突变的每个子图中都有一个单独的模式和 Apollo 服务器?应该S1直接调用S2“内部apollo服务器”吗?

默认情况下,所有面向用户的请求都需要经过 JWT 授权,但内部通信无需经过此授权即可正常工作。

子图在公共网络上不可用,但它们在同一内部网络上运行。从技术上讲,他们可以看到对方。它们托管在 GKE 上。

Jus*_*ter 5

这实际上是我最喜欢的主题之一!首先,像往常一样,答案是视情况而定。抛开这些,让我们进入一些细节......

要考虑的主要变量是您的系统需要以多快的速度扩展,即您需要多少子图。以下是一些具有不同复杂程度和实施难度的解决方案。

呼叫网关

对于一些服务,例如您的示例中的 2 个服务,您可以轻松地从任一服务调用网关。这样做的优点是易于实现,对于只有 10 个左右子图或数据通常稀疏的小型公司来说,这是一种使用联合的好方法。但这种方法有明显的缺点:

  • 每个跃点都会 1. 重新授权,并且 2. 由于必须进行往返而增加了延迟。在非常大的微服务环境中(例如 Google、Facebook、Netflix 等),这可能会成为问题,因为某些功能可能具有 10-20 个服务的垂直调用堆栈,并且所有这些都需要在 200 毫秒内解决才能满足 SLO要求。如果在每一跳您都需要执行到网关的往返(其中包括授权和加密),那么这将是一个大问题。如果该功能没有任何用户隐私问题,许多服务甚至不会进行服务间加密。

  • 您需要小心循环依赖。网关不会知道内部服务正在进行调用,而是照常完成请求。如果你是一个小团队,这听起来很容易,但随着事情的发展,你最终可能会出现 S1 -> S2 -> S3 -> S4 -> S5 -> S1 的依赖关系,甚至没有意识到这一点,而且它可能会慢慢蔓延小边缘情况并且难以调试。循环依赖始终是大型系统中的一个潜在问题,但通过使用网关,如果不深入了解每个查询的整个调用树,就很难捕获它。

  • 您将被限制在与客户相同的视图字段中。使用此方法,服务无法在内部提供可能对执行某些操作有用的附加信息。这可能类似于您可能不希望用户能够查询的库存库存。

重要的是要注意,大多数这些问题只会在中等规模左右开始成为交易破坏者,因此在决定反对此方法之前值得评估您的需求。

直接调用子图

如果子图设计为具有适当的基于关注的分离,那么您需要的信息应该可以从子图中获得,而不需要网关来解析其他字段。这解决了直接调用网关的延迟问题,并使管理依赖关系图变得更加容易。它没有解决上面讨论的视场问题。这是我个人所做的,但这似乎是一个有争议的模式。

注意:您提到一切都在 GKE 中运行。您可以使用集群本地 dns 来访问服务,但我强烈建议您研究服务网格来解决子图之间的路由问题。Istio、Nginx Service Mesh 和 LinkerD 是值得考虑的几个选项。

使用内部背板

随着系统的不断发展,将超级图视为产品的后端变得越来越重要。产品的内部设计很可能不会只使用graphql。大公司甚至会开发整个独立的内部平台,如果它能解决他们经常遇到的问题。在此示例中,这些系统可能不需要添加到超级图中。这与您使用“内部 apollo 服务器”的示例很接近,但老实说我建议仅使用 REST 或 gRPC。为了保持微服务架构的精神,您甚至可以让主服务使用 gRPC,而向网关注册的子图将只是 gRPC 服务器的视图层。