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

简介: 云计算设计模式(四)——消费者的竞争模式 允许多个并发用户处理在同一个通讯通道接收的消息。这种模式使系统能够同时处理多个邮件,以优化吞吐量,提高可扩展性和可用性,以及平衡工作负载。

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


允许多个并发用户处理在同一个通讯通道接收的消息这种模式使系统能够同时处理多个邮件,以优化吞吐量提高可扩展性和可用性以及平衡工作负载


背景和问题


在云中运行的应用程序,可以预计,以处理大量的请求而不是过程的每个请求同步地一个常用的方法是通过一个消息传送系统到该异步地处理它们的另一服务消费者服务),以通过他们应用程序。这种策略有助于确保在应用程序业务逻辑没有被阻塞,而正在处理的请求

请求的数量可以随着时间的原因有很多显著变化突然一阵用户活动聚集的请求,来自多个租户未来可能会导致不可预测的工作负载在高峰时间的系统可能需要处理许多每秒数百个请求而在其他时间的数量可能是非常小的。此外,该工作的性质进行的处理这些请求可能是高度可变的使用消费者服务的单个实例,可能会导致该实例成为充斥请求消息传送系统可通过消息从应用程序的流入被重载。为了处理这种波动的负载,该系统可以运行消费者服务的多个实例。然而这些消费者必须协调,以确保每个消息只传送给一个单个消费者工作量需要跨消费者负载平衡,以防止一个实例成为瓶颈

 

解决方案


使用消息队列来实现应用消费者服务实例之间的通信信道。消息队列中的形式应用请求,以及消费者的服务实例从队列中接收消息并对其进行处理。这种方法使消费者的服务实例同一池中从应用程序的任何实例处理消息图1示出了该架构

 

图1 - 使用消息队列分发工作提高到一个服务的实例


该解决方案具有以下优点
它使固有的负载调平系统,可以处理应用程序实例发送请求量很大的变化队列充当应用程序实例消费者服务实例,这有助于最大限度地减少应用程序和服务实例所描述的基于队列的负载调平模式的可用性和响应性的影响之间的缓冲区。处理的消息,需要一些将被执行时,不会妨碍同时由消费者服务的其他实例所处理的其它消息长期运行的处理。
•它提高了可靠性如果一个生产者直接与消费者,而不是使用这种模式进行通信不监视消费者,有一个概率的消息可能丢失失败,如果消费者无法进行处理。这种模式的消息不被发送一个特定的服务实例,一个失败服务实例不会阻塞一个生产者和消息可以通过任何加工服务实例进行处理。
它不需要复杂的协调消费者之间,或在生产者和消费者的实例。消息队列确保每个消息传递至少一次
它是可扩展的该系统能够动态地增加或减少消费者服务的实例的数目的消息量是波动的。
它可以提高弹性,如果消息队列提供事务读取操作如果消费者服务实例能够读取和处理该消息作为一个事务操作的一部分,并且如果这种消费服务实例随后发生故障时,这种模式可以确保该消息将被返回到队列中被拾起处理通过另一个实例消费者服务


问题和注意事项


在决定如何实现这个模式时,请考虑以下几点
留言订购其中消费者服务实例接收消息顺序是无法保证的,并且不一定反映所创建的消息的顺序。设计系统,以确保信息的处理是幂等的,因为这将有助于消除消息的处理顺序上的任何依赖。有关幂等的详细信息,请参阅乔纳森·奥利弗的博客幂等模式​​。


 注意:

微软Azure服务总线队列可以通过使用消息先入先出消息的顺序工具保证。欲了解更多信息,请参阅消息传递模式MSDN上使用会话


设计服务永续性。如果系统被设计为检测重新启动失败的服务实例中,可能有必要执行由服务​​实例执行作为幂等操作,以最小化被检索处理一次以上的单个消息的影响的处理。
•检测有害消息格式不正确的消息或者需要访问不可用的资源的任务可能会造成服务实例失败。该系统应避免这样的消息返回到队列,而是捕获和别处存储这些信息的详细信息,以便可以在需要进行分析。
处理结果服务实例处理一个消息从生成该消息的应用程序逻辑完全分离,并且它们未必能够直接进行通信如果服务实例生成必须传回给应用程序逻辑结果,该信息必须被存储在一个位置,都可以访问两个系统必须提供某种指示的处理已经完成,以防止应用逻辑检索数据不全


 注意:

如果您正在使用Azure的工作进程可能能够通过使用专用的邮件回复队列结果应用程序逻辑应用逻辑必须能够将这些结果与原来的消息关联起来这种情况下进行了更详细异步消息的引物进行说明。


扩展信息系统一个大型的解决方案,一个消息队列可以是不堪重负的消息的数量,并成为系统中的瓶颈。这种情况下,考虑分割该消息系统直接特定制造商的信息到一个特定的队列使用负载平衡,以跨多个消息队列分发消息
邮件系统可靠性保障一个可靠的消息传送系统,需要保证的是,一旦应用程序放入队列的消息也不会丢失这是确保所有邮件传递至少一次重要的

使用这个模式



使用这种模式
工作量为一个应用程序被分成异步运行任务。
•任务是独立的,可以并行地运行
工作容积变化很大需要一个可扩展的解决方案
该解决方案必须提供高可用性,并且如果处理一个任务失败必须是有弹性的。

这种模式可能不适合
•它是不容易的应用程序的工作负荷分离成离散的任务,任务之间的依赖程度高。
任务必须同步进行应用逻辑必须等待任务完成后再继续
•任务必须以特定的顺序来执行。 


Note

有些邮件系统支持会话,使生产者对消息进行分组在一起,并确保它们都被同一个接收者处理。这个机制可以与优先消息使用(如果它们支持)来实现消息排序的一种形式,顺序从生产者传送消息到单个消费者 
 

例子

Azure提供存储队列服务总线队列,可作为一个合适的机制来实现这种模式。应用逻辑可以发布消息一个队列,而消费者实现为一个或多个角色的任务可以检索这个队列中的消息并进行处理。对于弹性,一个服务总线队列使得消费者使用PeekLock模式,当它从队列检索消息这种模式实际上不是删除消息而只是其他消费者隐藏它处理完原来的用户可以删除该邮件。如果消费者失败,偷看将超时,消息将再次变得可见消费者找回它


Note

有关使用Azure的服务总线队列的详细信息,请参阅服务总线队列,主题和MSDN上的订阅。有关使用Azure存储队列的信息请参阅如何MSDN上使用队列存储服务

可供下载例子CompetingConsumers解决方案的QueueManager下面的代码显示了本指南说明了如何通过在网络辅助角色开始的事件处理程序使用QueueClient实例中创建一个队列

private string queueName = ...;
private string connectionString = ...;
...

public async Task Start()
{
  // Check if the queue already exists.
  var manager = NamespaceManager.CreateFromConnectionString(this.connectionString);
  if (!manager.QueueExists(this.queueName))
  {
    var queueDescription = new QueueDescription(this.queueName);

    // Set the maximum delivery count for messages in the queue. A message 
    // is automatically dead-lettered after this number of deliveries. The
    // default value for dead letter count is 10.
    queueDescription.MaxDeliveryCount = 3;

    await manager.CreateQueueAsync(queueDescription);
  }
  ...

  // Create the queue client. By default the PeekLock method is used.
  this.client = QueueClient.CreateFromConnectionString(
    this.connectionString, this.queueName);
}

 

下面的代码片段显示了一个应用程序如何创建和发送一批消息队列

public async Task SendMessagesAsync()
{
  // Simulate sending a batch of messages to the queue.
  var messages = new List<BrokeredMessage>();

  for (int i = 0; i < 10; i++)
  {
    var message = new BrokeredMessage() { MessageId = Guid.NewGuid().ToString() };
    messages.Add(message);
  }
  await this.client.SendBatchAsync(messages);
}

下面的代码显示了如何消费服务实例可以从队列中一个事件驱动的方式接收消息processMessageTask参数ReceiveMessages为代表,它引用在收到消息运行的代码此代码是异步运行。

private ManualResetEvent pauseProcessingEvent;
...

public void ReceiveMessages(Func<BrokeredMessage, Task> processMessageTask)
{
  // Set up the options for the message pump.
  var options = new OnMessageOptions();

  // When AutoComplete is disabled it is necessary to manually
  // complete or abandon the messages and handle any errors.
  options.AutoComplete = false;
  options.MaxConcurrentCalls = 10;
  options.ExceptionReceived += this.OptionsOnExceptionReceived;

  // Use of the Service Bus OnMessage message pump. 
  // The OnMessage method must be called once, otherwise an exception will occur.
  this.client.OnMessageAsync(
    async (msg) =>
    {
      // Will block the current thread if Stop is called.
      this.pauseProcessingEvent.WaitOne();

      // Execute processing task here.
      await processMessageTask(msg);
    },
    options);
}
...

private void OptionsOnExceptionReceived(object sender, 
  ExceptionReceivedEventArgs exceptionReceivedEventArgs)
{
  ...
}

需要注意的是自动缩放的功能,例如可天青,可用于启动和停止的角色实例队列长度的波动欲了解更多信息,请参阅自动缩放指导另外,没有必要维持角色实例工人之间的一对一的对应过程单个角色实例可以实现多个工作进程。欲了解更多信息,请参阅计算资源整合模式

本文翻译自MSDN:http://msdn.microsoft.com/en-us/library/dn568101.aspx

 

 

 

 

目录
相关文章
|
2月前
|
设计模式 前端开发 搜索推荐
前端必须掌握的设计模式——模板模式
模板模式(Template Pattern)是一种行为型设计模式,父类定义固定流程和步骤顺序,子类通过继承并重写特定方法实现具体步骤。适用于具有固定结构或流程的场景,如组装汽车、包装礼物等。举例来说,公司年会节目征集时,蜘蛛侠定义了歌曲的四个步骤:前奏、主歌、副歌、结尾。金刚狼和绿巨人根据此模板设计各自的表演内容。通过抽象类定义通用逻辑,子类实现个性化行为,从而减少重复代码。模板模式还支持钩子方法,允许跳过某些步骤,增加灵活性。
134 11
|
3月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
|
20天前
|
设计模式
「全网最细 + 实战源码案例」设计模式——模式扩展(配置工厂)
该设计通过配置文件和反射机制动态选择具体工厂,减少硬编码依赖,提升系统灵活性和扩展性。配置文件解耦、反射创建对象,新增产品族无需修改客户端代码。示例中,`CoffeeFactory`类加载配置文件并使用反射生成咖啡对象,客户端调用时只需指定名称即可获取对应产品实例。
82 40
|
21天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——简单工厂模式
简单工厂模式是一种创建型设计模式,通过工厂类根据传入参数创建不同类型的对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。适用于对象种类较少且调用者无需关心创建细节的场景。
52 19
|
19天前
|
设计模式 Java
「全网最细 + 实战源码案例」设计模式——生成器模式
生成器模式(Builder Pattern)是一种创建型设计模式,用于分步骤构建复杂对象。它允许用户通过控制对象构造的过程,定制对象的组成部分,而无需直接实例化细节。该模式特别适合构建具有多种配置的复杂对象。其结构包括抽象建造者、具体建造者、指挥者和产品角色。适用于需要创建复杂对象且对象由多个部分组成、构造过程需对外隐藏或分离表示与构造的场景。优点在于更好的控制、代码复用和解耦性;缺点是增加复杂性和不适合简单对象。实现时需定义建造者接口、具体建造者类、指挥者类及产品类。链式调用是常见应用方式之一。
49 12
|
21天前
|
设计模式 关系型数据库
「全网最细 + 实战源码案例」设计模式——工厂方法模式
简单工厂模式是一种创建型设计模式,通过一个工厂类根据传入参数创建不同类型的产品对象,也称“静态工厂方法”模式。其结构包括工厂类、产品接口和具体产品类。适用于创建对象种类较少且调用者无需关心创建细节的场景。优点是封装性强、代码复用性好;缺点是扩展性差,增加新产品时需修改工厂类代码,违反开闭原则。
42 15
|
3月前
|
设计模式 开发者 Python
Python编程中的设计模式:工厂方法模式###
本文深入浅出地探讨了Python编程中的一种重要设计模式——工厂方法模式。通过具体案例和代码示例,我们将了解工厂方法模式的定义、应用场景、实现步骤以及其优势与潜在缺点。无论你是Python新手还是有经验的开发者,都能从本文中获得关于如何在实际项目中有效应用工厂方法模式的启发。 ###
|
3月前
|
人工智能 边缘计算 云计算
2024.11|云计算行业的商业模式创新方法及实践
截至2024年,全球云计算行业迈入全新阶段,从IaaS到大规模AI模型平台,技术与商业模式不断创新。本文分析全球最新技术进展,探讨云计算商业模式创新策略与实践,解析云服务厂商如何通过技术革新实现价值最大化,推动企业数字化与智能化转型。重点讨论AI与云计算的深度融合、边缘计算与去中心化发展、平台化与生态系统建设,以及数据安全与绿色云计算等关键议题。
193 30
|
3月前
|
设计模式 安全 Java
Kotlin - 改良设计模式 - 构建者模式
Kotlin - 改良设计模式 - 构建者模式
|
3月前
|
设计模式 安全 Java
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
Kotlin教程笔记(51) - 改良设计模式 - 构建者模式
62 1

热门文章

最新文章

相关实验场景

更多