如何使微服务通信


【编者的话】本文讨论了两类微服务通信的方法:无代理通信和有代理通信,并总结了各自的优缺点。作者指出能明白何时使用何种方式才是最重要的,并建议初始使用无代理通信,有需要的情况下再转向成熟的代理,并可两种方式结合使用。

我确定你要构建可扩展的应用程序,对吗?谁都不会否认吧?如果是这样,你肯定听过“Cloud Native”(云原生)一词。这种方法就像天使一样,可以解决你的大多数扩展难题。那么,Cloud Native究竟是什么?

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

这是一种方法,不是一个框架,不需要一堆步骤。因此,有各种不同的方法可以达到云原生化,实现云计算。

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

这意味着每个微服务都位于不同的代码库中,并且正在独立部署。对于在那里的DevOps员工,你有一个专用于每个微服务的独立连续交付管道。

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

我们如何让微服务交流?

除了为微服务确定“前向兼容”API的困难之外,让它们进行交谈并不像看起来那么简单。你需要考虑多种因子,比如吞吐量延迟可伸缩性

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

因此,让我们开始吧。

无代理设计

图片一.jpeg

简介:这种方法让微服务直接相互通信。你可以使用HTTP进行传统的请求-响应,也可以使用websocket(或HTTP2)进行流式传输。

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

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

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


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


在很多情况下,无代理的设计根本行不通。你通常需要简单地发布一次消息,并让多个订阅者使用它。这是代理设计出现的地方。

消息总线(代理)设计

图片二.jpeg

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

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

优点:
  • 负载均衡:大多数消息代理都支持开箱即用的负载均衡。这使整个体系结构变得更加简单和高度可扩展。一些代理(如RabbitMQ)具有内置的重试功能,以及更多的使通信通道更可靠的功能。
  • 服务发现:使用消息传递作为后端时不需要服务发现。所有微服务均充当客户端。消息代理是唯一需要发现的服务。
  • 扇入和扇出:消息传递后端使分发工作负荷和汇总结果更加容易。最好的部分是添加工作程序微服务可以透明地完成,而不必更新其他微服务。


基于流的设计:这种方法也催生了流的概念。每个主题本质上都是消息流。任何用户都可以根据需要使用这些流。使用流对系统设计进行建模的可能性是无限的。

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


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

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

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

如果你选择基于微服务的体系结构,我总是建议进行事件驱动。事件驱动的体系结构可以看作是具有高级代理的核心,该代理具有内置的大量功能(如任务调度)。

总结

工作中使用正确的方法很重要。选择沟通方式是一项基本决定,需要格外小心。

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

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

原文链接:How to make microservices communicate?(翻译:池剑锋)

0 个评论

要回复文章请先登录注册