使用 gRPC and/or GraphQL 进行微服务架构
Using gRPC and/or GraphQL for microservice architecture
在我的公司,我们即将建立一个新的微服务架构,但我们仍在努力决定哪种协议最适合我们的用例。
在我们的例子中,我们有一些服务在内部被其他服务调用,但也通过 GraphQL API 网关向我们的客户公开。
选项 1:gRPC
gRPC 似乎是微服务内部通信的热门选择,因为它的性能和效率。
然而,gRPC 使得查询关系数据变得更加困难,并且需要更多的工作来连接到我们的 API 网关。
选项 2:GraphQL
另一种选择是让每个微服务实现自己的 GraphQL 模式,这样就可以在 API 网关中使用 Apollo Federation 轻松地将它们拼接在一起。
这种方法将使查询更加灵活,但由于缺少协议缓冲区,内部请求的性能会降低。
选项 3:两者?
也许另一种选择是通过在 gRPC 中实现突变和在 GraphQL 中实现查询来利用两全其美。或者只是创建两个 API,一个面向网关客户端,一个用于服务之间的通信。
问题
- 我们如何决定使用哪种方法?
- 有什么我们应该考虑的重要(不利)优势吗?例如。在易用性、可维护性、可扩展性、性能等方面?
- 这个用例是否有更好的替代方案?
我建议您应该使用 gRPC 进行内部服务通信,因为它速度很快。现在来了你应该使用什么来进行外部通信,你可以使用 REST 或 Graph QL。如果不同类型的客户端需要不同数量的数据,Graph QL 是一个不错的选择,否则 REST 将更容易实现。
在我的一个项目中,我们使用 gRPC 进行内部通信(服务使用 Go 语言),而对于外部通信,我们使用 REST。 Go 有一些包可以帮助开发使用 REST 公开的服务以及使用 gRPC 与其他服务进行内部通信。因此,在我们的场景中,它运行良好。
这取决于您正在实施的整体架构。
我建议同时使用 GraphQL 和 gRPC:
使用 Apollo Federation 作为边界节点来无缝处理来自使用 GraphQL 的前端的请求。
在您的 API 和微服务上使用 CQRS 模式,并将读取模型与写入模型严格分开。
使用六边形架构(我们使用Explicit Architecture in my company) to implement DDD - Domain-driven-design。
为了无缝集成 Apollo,您必须将 GraphQL 层实现到所有后端服务的架构中。
在读取模型中,实现 GraphQL 层。您将从联合中受益(来自多个微服务的数据的并行读取将在联合引擎中“加入”,而无需您的 API 节点的任何参与)。
对于写入模型(突变)中的后端服务之间的通信,请使用 gRPC。
gRPC 可以像在本地一样远程调用 CQRS 命令。
因此,您的远程微服务看起来就像本地后端代码的一部分。
-
您根本不必使用 REST 或 graphQL。它只是添加了一层。可以使用 grpc web 和 pull/push 之类的 pubsub 来实现。您还可以使用 FieldMask
执行 graphQL-like 行为
在我的公司,我们即将建立一个新的微服务架构,但我们仍在努力决定哪种协议最适合我们的用例。
在我们的例子中,我们有一些服务在内部被其他服务调用,但也通过 GraphQL API 网关向我们的客户公开。
选项 1:gRPC
gRPC 似乎是微服务内部通信的热门选择,因为它的性能和效率。
然而,gRPC 使得查询关系数据变得更加困难,并且需要更多的工作来连接到我们的 API 网关。
选项 2:GraphQL
另一种选择是让每个微服务实现自己的 GraphQL 模式,这样就可以在 API 网关中使用 Apollo Federation 轻松地将它们拼接在一起。
这种方法将使查询更加灵活,但由于缺少协议缓冲区,内部请求的性能会降低。
选项 3:两者?
也许另一种选择是通过在 gRPC 中实现突变和在 GraphQL 中实现查询来利用两全其美。或者只是创建两个 API,一个面向网关客户端,一个用于服务之间的通信。
问题
- 我们如何决定使用哪种方法?
- 有什么我们应该考虑的重要(不利)优势吗?例如。在易用性、可维护性、可扩展性、性能等方面?
- 这个用例是否有更好的替代方案?
我建议您应该使用 gRPC 进行内部服务通信,因为它速度很快。现在来了你应该使用什么来进行外部通信,你可以使用 REST 或 Graph QL。如果不同类型的客户端需要不同数量的数据,Graph QL 是一个不错的选择,否则 REST 将更容易实现。
在我的一个项目中,我们使用 gRPC 进行内部通信(服务使用 Go 语言),而对于外部通信,我们使用 REST。 Go 有一些包可以帮助开发使用 REST 公开的服务以及使用 gRPC 与其他服务进行内部通信。因此,在我们的场景中,它运行良好。
这取决于您正在实施的整体架构。
我建议同时使用 GraphQL 和 gRPC:
使用 Apollo Federation 作为边界节点来无缝处理来自使用 GraphQL 的前端的请求。
在您的 API 和微服务上使用 CQRS 模式,并将读取模型与写入模型严格分开。
使用六边形架构(我们使用Explicit Architecture in my company) to implement DDD - Domain-driven-design。
为了无缝集成 Apollo,您必须将 GraphQL 层实现到所有后端服务的架构中。
在读取模型中,实现 GraphQL 层。您将从联合中受益(来自多个微服务的数据的并行读取将在联合引擎中“加入”,而无需您的 API 节点的任何参与)。
对于写入模型(突变)中的后端服务之间的通信,请使用 gRPC。
gRPC 可以像在本地一样远程调用 CQRS 命令。
因此,您的远程微服务看起来就像本地后端代码的一部分。
您根本不必使用 REST 或 graphQL。它只是添加了一层。可以使用 grpc web 和 pull/push 之类的 pubsub 来实现。您还可以使用 FieldMask
执行 graphQL-like 行为