我想每个人都想构建一个可扩展的应用程序。
如果是这样,你肯定会遇到“Cloud Native”这个词。
这种方法就像一个天使,可以解决我们的大部分扩展挑战。
那么这究竟是什么呢?
云原生是一种用于构建可以利用云的所有功能的应用程序的方法。
这是一种方法。不是框架。没有一大步要遵循。因此,有一百万种不同的方法可以实现云原生并实现云计算“Moksha”。
云原生的一个关键原则是微服务。微服务是微小的(有时不是那么小)模块,可以彼此独立工作。
它们可能依赖于其他微服务甚至是数据库等数据持久层。但关键是要使用松散耦合。
微服务通过“通信”进行协调。
这意味着每个微服务都位于不同的存储库中,并且是独立部署的。对于DevOps人员,需要有一个专用于每个微服务的独立连续交付管道。
但这让我想到了最重要的问题。
我们如何让微服务说话?
撇开为微服务决定“ 前向兼容 ”API 的困难,只是让它们说话并不像看起来那么简单。
我们需要考虑多个参数。就是吞吐量,延迟和可伸缩性。
现在有很多方法可以对不同的通信方式进行分类。同步(阻塞)和异步(非阻塞)经常使用,但我觉得这些主要是编程语言的特征。我也将忽略半双工和全双工模式,因为现在在大多数云架构中使用它们甚至两者都很容易。
无代理设计
在这里,我们让我们的微服务直接相互通信。我们可以将HTTP用于传统的请求 - 响应,或使用websockets(或HTTP2)进行流式传输。
在两个或更多微服务之间绝对没有中间节点(路由器和负载平衡器除外)。
只要我们知道他们的服务地址和他们使用的API,我们就可以直接连接到任何服务。
让我们看看他们的优缺点。
优点:
1、低延迟:此方法具有尽可能低的延迟。
2、易于实施:无代理设计易于可视化和实施。
3、轻松调试:这种方法非常容易调试,尤其是我将要讨论的下一个方法。调试或跟踪错误的位置是分布式系统中的一个非常重要的主题。
4、高吞吐量:在这种机制中,更多的CPU周期实际上用于工作而不是路由。现在可能不是那么明显,但这个设计会使这一点更加明确。
缺点:
1、服务发现:在这样的设计中,服务发现至关重要。服务发现机制需要具有足够的响应性和可扩展性,以反映群集的最新状态。
2、连接梦魇:想象一下,如果所有的微服务都需要相互连接。这将是很多联系。大多数这些连接都相当空闲。结果,由此浪费了大量资源。
3、紧密耦合:从本质上讲,无代理设计是紧密耦合的。想象一下,你有一个微服务来处理在线支付。现在,您希望另一个微服务能够实时更新每分钟发生的付款次数。这将要求您在多个微服务中进行修改,这是不合需要的。
消息总线(代理)设计
在这种架构中,所有通信都通过一组代理人进行路由。代理是运行一些高级路由算法的服务器程序。
每个微服务都连接到代理。微服务可以通过相同的连接发送和接收消息。服务发送消息称为发布者,接收者称为订阅者。消息被发布到特定的“主题”。订阅者接收它已订阅的主题的消息。
优点:
1、负载平衡:大多数消息传递代理都支持开箱即用的负载平衡。
2、服务发现:使用消息传递后端时不需要服务发现。
3、扇入和扇出:消息传递后端使分发工作负载和聚合结果变得更加容易。最好的部分是添加工作微服务可以透明地完成,而无需更新其他微服务。
4、基于流的设计:这种方法也产生了流的概念。每个主题本质上都是一个消息流。任何订阅户都可以在需要时访问这些流。使用流建模系统设计的可能性是无穷无尽的。
缺点:
1、扩展代理:虽然优势是惊人的,但扩展代理本身对高度分散的系统来说是一个挑战。
2、更高的延迟:消息总线中的跳数增加了整体延迟。对于类似RPC的用例尤其如此。在关键任务应用程序中,这可能不是一个可行的解决方案。
3、更高的资源利用率:代理需要运行CPU,内存和存储资源。否则,这些资源可用于运行其他微服务。与代理设计相关的开销对于小型集群来说可能太多了。
仅了解各种架构的优缺点是不够的。知道何时使用什么很重要。
我们必须始终默认以无代理设计开始。如果我们需要流的灵活性或需要利用消息总线的pub-sub语义,请进行切换。如果你刚刚开始,那么从无代理设计开始然后在需求增加时切换是有意义的。
没有必要只选择一个。你可以使用两者。对于我们的工具,我们使用代理设计来实现RPC调用。与我们的数据库层的通信是无代理的,以提供较低的延迟。
使用正确的方法完成工作很重要。选择沟通方式是一项基本能力,需要谨慎对待。
两者都有多种选择。坚持一个完善的框架几乎总是比从头开始制作更有意义。那里有很多选择。对于消息代理,可以有RabbitMQ,Nats,Kafka等,每个都是为特定的消息传递语义而构建的。
另一种很棒的方法是使用Backend作为服务,如Space Cloud。Space Cloud将自动化整个后端,因此我们可以专注于业务逻辑而不是云架构。
閱讀更多 TE傳知學院 的文章