云计算设计模式翻译(四):Competing Consumers Pattern(消费者竞争模式)

简单地来说,这个模式能够使多个并行的consumer处理同一个信道中收到的消息,从而使系统能够并发地处理大量消息来优化系统的吞吐量,提高系统的可扩展性和可用性,平衡负载。

Context and Problem

一般来说,一个运行在云端的应用通常都需要处理大量的请求。相比于同步的方式来处理每一个请求来说,一个更加通用的技术是实现一个消息系统来实现异步地处理各个请求。另外,这种策略也能够使得业务逻辑不会在某个请求正在被处理时阻塞。

在系统运行过程中,有很多种原因会导致系统所处理的请求数量发生巨大变化。突然出现的用户活动或者是对多个系统使用者的消息汇聚都会引起一些意料之外(大)的负载。系统也许会在高峰时间段处理巨量的消息但在其他时间段只处理较少的消息,并且处理不同消息的逻辑可能差异非常大。由于这几个原因,如果在系统中只使用一个消息consumer(就是用来处理消息的应用,下同),那么这个consumer在高峰期就很有可能被海量的消息淹没,或者整个消息传递系统负载过高直接陷入瘫痪。为了解决这个问题,可以在系统中启动多个consumer实例,但这种情况下又必须协调好这些consumer实例,要确保每条消息只被其中之一拿到并处理;另外,也要做好负载均衡,避免其中某个consumer成为整个系统的瓶颈。

Solution

解决上面说的问题的方法就是用消息队列来作为用户程序(即消息的生产者)和消息消费者之间的通信媒介。用户程序将调用请求封装成一个消息放到消息队列中,consumer从消息队列中取出消息并进行处理。这个方法就能使同一个consumer池(包含了一堆consumer实例)中的consumer能够处理来自任意用户程序的请求。

这种解决方案有以下这些好处:

1.这种设计使那些负载水平固定的系统能够处理不同压力的用户请求。消息队列相当与在用户程序与consumer之间做了一个buffer,有助于减少压力波动时对用户程序和consumer稳定性、响应能力产生的影响。

2.这种设计能有助于提高系统可靠性。假设用户程序直接与consumer相连而不是使用这种模式(引入消息队列),并且不对消费者做任何监管,那么当消费者出现问题时请求就很有可能丢失或失败。然而在这种模式下用户程序并不是把消息发送给某个具体的consumer,而是一堆consumer在消息队列端竞争消息,另外,当消息失败时也不会造成用户程序的阻塞。

3.采用这种模式后就不需要在多个consumer之间或是用户程序与consumer之间做太多复杂的协调工作,消息队列本身可以保证消息至少被传递一次。

4.这种设计具有很好的易扩展性。consumer的数量可以根据请求压力的不同随意增减。

5.如果所使用的消息队列支持事务读(每个消息会且仅会被取到一次),那么这种设计就能提高系统的弹性。如果一个consumer读取并处理一个消息是作为一个事务性操作的一个步骤,当它抢到一个消息之后的执行过程中出现步骤,消息队列可以保证这条消息还会留存在队列中并被其他的consumer再次获取重复。

Issues and Considerations

在考虑如何实现这个模式时需要注意一下几点:

1.消息顺序:在多个consumer抢消息的情景下,consumer获得消息的顺序是无法保证的,并且也没有必要与消息创建的顺序相关联。在系统设计中要把消息处理过程设计成幂等的,这样就能消除消息处理顺序对处理结果的影响。

2.系统弹性:如果系统需要监管consumer服务并在其失败时进行重启,那么将操作设计成具有幂等性就更有必要了,这能将消息重复处理情况出现时对系统的影响降到最小。

3.检测“有毒的”消息:一个畸形的消息或者访问那些无法正常使用资源的任务极有可能会造成consumer的崩溃。对此,系统需要避免这种消息重新回流到消息系统中,并且捕获这个消息/任务的异常信息以便日后分析修复。

4.结果处理:consumer处理消息的逻辑与生成消息的业务逻辑是完全解耦的,并且不是以一种直接的方式进行通信的。如果consumer的处理结果必须发回给源消息对应的生产者,那么必须用一个两边都能访问到的容器来存储结果,并且系统要提供一个标志用于表明数据处理完成防止有一方访问不完整的数据。

5.消息系统的扩展性:在一个大规模数据处理情景下,单个消息队列很容易被大量的消息淹没从而成为整个系统性能的瓶颈。此时,可以考虑对整个消息系统(分布式的)进行分区,消息的producer只在自己所在的分区中发送消息;或者说可以将多个消息队列组合在一起,在它们之上加一层负载均衡。

6.确保消息系统的可靠性:一个可靠的消息系统需要保证当一个应用将一条消息插入到消息系统后,这条消息就绝不会丢失(哪怕处理失败),这是“保证每条消息至少被投递一次”这一原则的前提条件。

时间: 2024-10-12 14:59:33

云计算设计模式翻译(四):Competing Consumers Pattern(消费者竞争模式)的相关文章

Competing Consumers Pattern (竞争消费者模式)

Enable multiple concurrent consumers to process messages received on the same messaging channel. This pattern enables a system to process multiple messages concurrently to optimize throughput, to improve scalability and availability, and to balance t

云计算设计模式(四)——消费者的竞争模式

云计算设计模式(四)--消费者的竞争模式 允许多个并发用户处理在同一个通讯通道接收的消息.这种模式使系统能够同时处理多个邮件,以优化吞吐量,提高可扩展性和可用性,以及平衡工作负载. 背景和问题 在云中运行的应用程序,可以预计,以处理大量的请求.而不是过程的每个请求同步地,一个常用的方法是通过一个消息传送系统到该异步地处理它们的另一服务(消费者服务),以通过他们的应用程序.这种策略有助于确保在应用程序的业务逻辑没有被阻塞,而正在处理的请求. 请求的数量可以随着时间的原因有很多显著变化.突然一阵在用

云计算设计模式(十五)——管道和过滤器模式

云计算设计模式(十五)——管道和过滤器模式 分解,执行复杂处理成一系列可重复使用分立元件的一个任务.这种模式可以允许执行的处理进行部署和独立缩放任务元素提高性能,可扩展性和可重用性. 背景和问题 一个应用程序可能需要执行各种关于它处理的信息不同复杂的任务.一个简单,但不灵活的方式来实施这个应用程序可以执行此处理为单一模块.然而,这种方法有可能减少用于重构代码,对其进行优化,或者重新使用它,如果是在应用程序中其他地方所需要的相同的处理的部件的机会. 图1通过使用单片式的方式示出了与处理数据的问题.

云计算设计模式(二十)——调度程序代理管理者模式

云计算设计模式(二十)——调度程序代理管理者模式 协调一系列在分布式服务集和其他远程资源的的行为,试图透明地处理故障,如果这些操作失败,或撤销,如果系统不能从故障中恢复执行工作的影响.这种模式可以分布式系统中增加弹性和灵活性,使之恢复和重试失败是由于短暂的异常,持久的故障和处理故障等操作. 背景和问题 应用程序执行其包括多个步骤,其中的一些可以调用远程服务或访问远程资源的任务.各个步骤可以是相互独立的,但它们是由实现该任务的应用程序逻辑编排. 只要有可能,应用程序应该确保任务运行完成和解决远程访

云计算设计模式翻译(五):Compute Resource Consolidation Pattern

这个模式所做的事情概括一下就是把多个不同的任务和操作合并到一个计算单元中,从而使云计算应用提高计算资源利用率,降低管理开销和任务之间连接交互的开销. PS:我这里对后文中所翻译的"计算单元"做个小小的注释,这里的计算单元可以认为是逻辑的运行容器,可以是基于cgroup的各种container,也可以是像Storm中的worker,Spark中的Executor等等.这个模式除了在自己设计分布式系统时能作为参考,在使用像Storm或Spark这样的框架时也很具有参考意义,可以帮助配置优化

云计算设计模式翻译:Cache-Aside Pattern

这个手册其实老早就搞到了,只是最近实在太懒了一直没动- - ,希望能坚持把主要的内容翻译完.翻译的过程中会加入一些自己的看法,如果有不准确或错误的地方欢迎各种提意见指出~. 简单来说就是将数据从持久化存储中加载到cache中.这个模式可以提升系统性能,并且保证cache和底层存储中数据的一致性.PS:下文会用"存储空间"来表示data store,在实际的工程中可以代表数据库.文件等持久化到硬盘的存储容器. Context and Problem  传统的应用程序中经常使用cache来

云计算设计模式翻译(三):Compensating Transaction Pattern(事务修正模式)

先说明一下:这个模式的中文我一直找不到一个比较恰当的中文来表述,姑且在本文中称之为事务修正模式吧,如果各位觉得有更合适的称呼欢迎提出. 这个模式指的是对于一个由一系列步骤组成.并遵循最终一致性的操作来说,如果一个或多个中间步骤发生错误,那么就必须要对这次操作的步骤进行撤销.对于一个实现了复杂业务逻辑和工作流的云端应用来说,遵循最终一致性的操作随处可见,所以本模式应用场景还是比较多得. Context and Problem 运行在云端的应用程序通常会频繁地修改数据,而这些数据通常会在分布在不同物

云计算设计模式翻译(二):Circuit Breaker Pattern(断路器模式)

当连接使用远端服务或资源时,可能需要花不少精力来做好错误处理.这个模式可以有效提高程序的稳定性和弹性. Context and Problem 在像云这种分布式的环境中,应用程序的操作经常访问远端的资源和服务.然而这类操作有可能因为网络响应慢.超时.资源暂时不可用等瞬时性故障(transient faults)而失败.这些故障通常情况下会在一小段时间后自动恢复,而对于一个好的云应用来说,必须要有一个好的策略(比如尝试重试)来处理这种情况. 但是有时候错误是由一些难以预期的异常事件导致的,这种情况

云计算设计模式系列文章

云计算设计模式(一)——缓存预留模式 云计算设计模式(二)——断路器模式 云计算设计模式(三)——补偿交易模式 云计算设计模式(四)——消费者的竞争模式 云计算设计模式(五)——计算资源整合模式 云计算设计模式(六)——命令和查询职责分离(CQRS)模式 云计算设计模式(七)——事件获取模式 云计算设计模式(八)——外部配置存储模式 云计算设计模式(九)——联合身份模式 云计算设计模式(十)——守门员模式 云计算设计模式(十一)——健康端点监控模式 云计算设计模式(十二)——索引表模式 云计算设