微服务如何通信


【编者的话】微服务非常棒,但如果无法通信,它们将不会有太大用处。阅读下文来获取必要的架构概述。

我相信你要构建可扩展的应用程序,对吗?谁不想呢?如果是这样,你一定遇到过“云原生”一词。它就像天使一样,可以解决你的大多数扩展难题。那么,云原生究竟是什么?

云原生是一种用于构建可以利用云的所有功能的应用程序的方法。

是的,你说的没错,它是一种方法,不是一个框架,没有一堆可遵循的步骤。因此,有成千上万种不同的方法可以使云原生化并实现云计算“解脱”。

云原生的一个关键原则是微服务。微服务是很小的模块(有时不是那么小),它们可以彼此独立地工作。它们可能依赖于其他微服务,甚至依赖于数据库等数据持久层,但是关键是要使用松耦合。微服务通过“通信”进行协调。

视频

这意味着每个微服务都位于不同的存储库中,并且独立部署。对于 DevOps,你有一个专用于每个微服务的独立的连续交付管道。

这使我想到了最重要的问题。

现在,有很多方法可以对不同的通信模式进行分类。同步(阻塞)和异步(非阻塞)被经常使用,但我觉得这些主要是编程语言的特征。我将不考虑半双工模式还是全双工模式,因为目前在大多数云架构中很容易使用其中一种(或两种)。

让我们深入研究吧。

无代理模式

1.jpeg

这是什么:在这里,我们使微服务直接相互通信。你可以使用 HTTP 进行传统的请求响应,也可以使用 websocket(或 HTTP2)进行流式传输。

两个或多个微服务之间绝对没有中间节点(路由器和负载均衡器除外)。你可以直接连接到任何服务,只要你知道它们的服务地址和它们使用的 API。

听起来很基础,对吗?差不多是。有一些很棒的协议,例如 GRPC,可以使生活更加轻松。

优点:
  • 低延迟:此方法具有最低的延迟。这里没有代理,因此它很快。施加的限制主要是由于不良的 API 实现。但是同样,GRPC 之类的工具可确保您在 API 层获得最佳性能。
  • 易于实施:无代理的设计易于可视化和实施。这使生活变得更加轻松,世界变得更加幸福。
  • 易于调试:这种方法非常易于调试,尤其是在我要讨论的下一个方法中。在分布式系统中,调试或跟踪错误所在的位置非常重要。一天多次发布新版本时,这一点变得尤为重要。
  • 高吞吐量:在这种机制中,实际上是在工作而不是路由上花费了更多的CPU。现在可能还不那么明显,但是有代理的设计会使这一点更加清楚。大多数数据库 API 实际上使用无代理设计也就不足为奇了。


缺点:
  • 服务发现:在这种设计中,服务发现至关重要。服务发现机制需要具有足够的响应能力和可伸缩性,以反映集群的最新状态。
  • 连接噩梦:想象一下所有微服务需要相互连接,那将有很多联系。这些连接大多数都是相当空闲的。结果,浪费了很多资源。
  • 紧耦合:从本质上讲,无代理设计是紧耦合的。假设您有一个微服务来处理在线支付,现在您希望另一个微服务能够为您提供每分钟发生的付款数量的实时更新。这将需要您在多个微服务中进行修改,这是不希望的。


在许多情况下,无代理的设计是行不通的。您通常需要简单地发布一次消息,并让多个订阅者消费它。这就是代理模式。

消息传递总线(代理)设计

2.jpeg

简介:在这种体系结构中,所有通信都通过一组代理进行路由。代理是运行某些高级路由算法的服务器程序。

每个微服务都连接到代理,微服务可以通过相同的连接发送和接收消息。发送消息的服务称为发布者,接收者称为订阅者。消息被发布到特定的“主题”。订阅者接收那些已订阅的主题的消息。

优点:
  • 负载均衡:大多数消息代理都支持开箱即用的负载均衡。这使整个体系结构变得更加简单和高度可扩展。一些代理(例如 RabbitMQ)具有内置的重试功能,以及更多的使通信通道更可靠的功能。
  • 服务发现:使用后端消息传递时不需要服务发现,所有微服务均充当客户端。唯一需要发现的服务是消息代理。
  • 输入和输出:消息传递后端使分发工作负载和汇总结果变得更加容易。最好的是可以透明地添加工作微服务,而不必更新其他微服务。
  • 基于流的设计:这种方法也催生了流的概念。每个主题本质上都是消息流,任何订阅者都可以在需要时使用这些流,使用流对系统设计进行建模的可能性是无限的。


缺点:
  • 扩展代理:尽管优势惊人,但扩展代理本身对于高度分布式的系统而言是一项挑战,这是与维护微服务一起的另一项工作。
  • 较高的延迟:消息总线中的节点数会增加总体延迟。对于类似 RPC 的用例尤其如此。在关键应用中,这可能不是可行的解决方案。
  • 更高的资源利用率:代理需要 CPU、内存和存储资源才能运行。否则,可以将这些资源用于运行其他微服务。对于小型集群而言,与代理设计相关的开销可能太大。


仅仅了解各种架构的优缺点是不够的,重要的是要知道何时使用什么。

您必须始终默认使用无代理设计。如果需要流的灵活性或需要利用消息总线的pub-sub语义,请进行切换。如果您是从头开始,那么就可以从无代理设计开始,然后在需求增加时切换。

不必只选择一个,你可以同时使用两个。对于我们的工具,我们正在使用代理设计来实现 RPC 调用。与数据库层的通信是无代理的,以提供较低的延迟。

如果你选择基于微服务的体系结构,我推荐进行事件驱动。事件驱动架构可以看作是具有高级代理的核心,该代理内置了很多功能(例如任务调度)。

总结

对任务使用正确的方法很重要。选择通信方式是一项基本决定,需要格外小心。

两者都有多个选项,坚持一个完善的框架几乎比从头开始做更有意义。有很多选择,对于消息代理,你可以使用 RabbitMQ,NatsKafka 等,并且每个代理都是针对特定的消息语义而构建的。

另一个很棒的方法是使用后端即服务,例如 Space Cloud。Space Cloud将使整个后端自动化,因此您可以专注于业务逻辑而不是云架构。

原文链接:How to Make Microservices Communicate (翻译:xiebo)

0 个评论

要回复文章请先登录注册