想象一下,构建一台复杂的机器,其中有无数独立的部件,每个部件都在执行自己的功能,但所有部件都需要有效地相互通信才能完成任务。这就是我们在设计云原生应用时面临的挑战,这些应用由相互连接的微服务和无服务器组件组成。在本文中,我们将探讨设计稳健而有弹性的通信系统的具体细节,该系统可以有效协调应用边界内外的这些独立元素。
这些细粒度的服务采用各种同步或异步通信方法进行内部和外部交互。在同步通信中,一个服务使用 HTTP 或 gRPC 调用另一个服务,在指定的时间内等待响应,然后再继续。与此相反,异步通信涉及交换消息而不期待立即响应。RabbitMQ 或 Kafka 等消息代理作为中介,缓冲消息以确保可靠的交付。在云原生应用中,结合使用多种通信模式通常是一种实用的方法。让我们先从同步通信开始。
什么是同步通信?
同步通信就像对话。一个服务(我们称之为服务 A)发起请求,然后等待另一个服务(服务 B)或外部 API 的响应。这就好比提出问题并等待答案。服务 A 通过 HTTP 发送请求并等待。它要么在等待服务 B 的响应,要么在等待最长等待时间到期。在等待期间,服务 A 会暂时被阻塞,就像一个人暂停活动等待响应一样。这种模式通常被称为请求-响应模式,实现起来相对简单。但是,广泛使用这种模式会带来挑战,需要仔细考虑。
同步通信的挑战
虽然同步通信是我们云原生工具包中的一个强大工具,但它也带来了一系列需要仔细考虑的挑战。
时间耦合
在整个解决方案中过度依赖同步通信会导致时间耦合问题。当大量同步调用串联在一起时,会导致客户端应用程序接收响应的等待时间延长。
可用性依赖
同步通信要求所有通信服务同时可用。如果后端服务承受意外负载,客户端应用程序可能会因超时错误而出现故障,从而影响整体性能。
网络质量影响
网络质量会直接影响同步通信的性能,包括可用带宽和响应在服务后端服务之间传输所需的时间。
尽管存在这些挑战,同步通信在特定场景中仍能证明其价值。让我们在下一节探讨一些使用案例,在这些案例中,同步通信可能是更好的选择。
何时使用同步通信
在某些情况下,使用同步通信会被证明是更好的选择。
实时数据访问或保证结果
当需要即时或实时反馈时,同步通信可提供高效率。例如,当客户在电子商务网站上下单时,电子商务前端需要检查库存系统,以确保商品有库存。这是一个同步操作,因为应用程序需要等待库存系统的响应,然后才能继续处理订单。
协调依赖任务序列
在服务必须执行一系列任务的情况下,同步通信可以维持秩序。它特别适用于任务顺序至关重要的工作流。
保持事务完整性
当多个组件之间保持数据一致性至关重要时,同步通信可帮助保持原子事务。它适用于金融交易等数据完整性至关重要的场景。
同步通信是一个功能强大的工具,但也有它的挑战。好消息是,我们还可以选择异步通信,一种可以与同步方法一起工作的补充方式。让我们在下一节中进一步探讨。
什么是异步通信?
异步通信模式为服务间通信提供了一种动态、高效的方法。与同步通信不同,异步通信允许服务在不等待立即响应的情况下发起请求。在这种模式中,响应可能不是即时的,也可能是在单独通道(如回调队列)上异步到达的。这种通信模式依赖于高级消息队列协议(AMQP)等协议和消息传递中间件,包括消息代理或事件代理。
这种消息传递中间件充当中介,业务逻辑最少。它从源或生产者服务接收消息,然后将消息传递给预定的消费服务。集成消息中间件可以大大提高这种解耦方法的弹性和容错性。异步通信包含多种实现方式。
一对一通信
在一对一消息通信中,生产者使用消息代理将消息专门发送给接收者。通常情况下,消息代理依靠队列来确保可靠的通信,并提供交付保证,如至少交付一次。这种实现方式类似于命令模式,其中交付的消息作为命令被订阅者服务使用,以触发操作。
让我们以网上零售店为例说明其用途。在线业务在很大程度上依赖于其网站的可靠性。该模式提供容错和消息保证,确保一旦客户在网站上下单,后端执行系统就能收到订单并进行处理。即使后端系统宕机,消息代理也会保留消息,并在可以处理这些消息时进行交付。例如,在电子商务应用中,当客户下订单时,订单详细信息可以通过消息代理作为消息从订单服务(生产者)发送到履行服务(消费者)。这就是一对一通信的一个例子。
一对一消息模式的扩展是异步请求-回复模式。在这种情况下,调度程序发送消息而不期望得到响应。但在一些特定情况下,消费者必须利用同一消息代理基础架构队列中的队列来响应生产服务。消费者的响应可能包含额外的元数据,如 ID(用于关联初始请求)或地址(用于响应)。由于生产者并不期望立即得到回复,因此需要一个独立的生产者工作流来管理这些回复。一旦订单发送完毕,履行服务(消费者)就会回复前端订单服务(生产者),以便在网站上更新客户信息。
当两个服务进行点对点通信时,单个消费者通信就派上用场了。然而,在某些情况下,发布者必须向多个订阅者发送一个特定事件,这就导致了下面的模式。
一对多通信
当单个组件(发布者)需要向多个组件和服务(订阅者)广播一个事件时,这种通信方式就很有价值。一对多通信使用主题概念,类似于在线论坛。
它就像一个在线论坛,多个用户可以在论坛上发表文章,而他们的追随者可以在自己的时间内阅读这些文章,并做出适当的回应。同样,应用程序可以有主题,生产者服务可以向这些主题写文章,消费服务可以从主题中读取文章。这是现实世界应用中最流行的模式之一。
再考虑到电子商务平台有一个更新产品价格的服务,而多个服务都需要这一信息(如订阅服务、推荐服务等),那么价格更新可以作为一条消息发送到消息代理中的一个主题。所有感兴趣的服务(订阅者)都可以监听该主题并接收价格更新。这就是一对多通信的一个例子。有几种工具可以实现这种模式,其中 Apache Kafka、Redis Pub/Sub、Amazon SNS 和 Azure Event Grid 是最受欢迎的选择。
异步通信的挑战
异步通信在带来诸多好处的同时,也带来了一系列挑战。
弹性和容错
微服务和无服务器组件数量众多,每个组件都有多个实例,因此出现故障在所难免。实例可能会崩溃、不堪重负或出现瞬时故障。此外,发送方不需要等待消息被处理,因此它可能不会立即意识到错误的发生。我们必须采取以下策略
- 重试机制: 针对瞬时故障重试失败的网络调用
- 断路器模式: 防止重复调用故障服务,以避免资源瓶颈
分布式跟踪
异步通信可能跨越多个服务,这给监控整体系统性能带来了挑战。实施分布式跟踪有助于将日志和指标联系在一起,从而了解事务流。
复杂的调试和监控
异步通信可能更难调试和监控,因为操作不是按照线性流程进行的。要有效调试和监控这些系统,通常需要专门的工具和技术。
资源管理
异步系统通常涉及长期连接和后台处理,这可能会给资源管理带来挑战。必须注意有效地管理资源,防止内存泄漏或过度使用 CPU。
了解这些挑战有助于在云原生应用中设计更稳健、更有弹性的异步通信系统。
结束语
同步和异步通信模式之间的选择并不是二元对立的,而是根据应用程序的具体要求做出的战略性决定。
同步通信易于实现,并能提供即时反馈,因此适用于实时数据访问、协调依赖任务和维护事务完整性。不过,同步通信也面临着时序耦合、可用性依赖和网络质量影响等挑战。
另一方面,异步通信允许服务在不等待立即响应的情况下启动请求,从而提高了系统的响应速度和可扩展性。异步通信具有灵活性,非常适合不需要立即反馈的情况。不过,它在弹性、容错、分布式跟踪、调试、监控和资源管理方面带来了复杂性。
总之,为云原生应用设计稳健、弹性的通信系统需要深入了解同步和异步通信模式。通过仔细考虑每种模式的优缺点并将其与需求相结合,架构师可以设计出有效协调应用边界内外独立元素的系统,从而提供高性能、可扩展和可靠的云原生应用。
作者:Gaurav Gaur
译自:https://dzone.com/articles/decoding-synchronous-and-asynchronous-communicatio
本文来自作者投稿,版权归原作者所有。如需转载,请注明出处:https://www.nxrte.com/jishu/46676.html