微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > 如何构建应用程序引擎以及使用 Windows Azure Storage 实现异步消息传送

如何构建应用程序引擎以及使用 Windows Azure Storage 实现异步消息传送

时间:02-18 来源:互联网 点击:

心存怀疑的开发人员提出的最大疑问之一是他们如何在云中继续运行后台进程,即他们的引擎如何继续运行。本文旨在通过向您演示如何构建应用程序引擎以及使用 Windows Azure Storage 实现异步消息传送和处理来为您揭开云中缺乏后台处理的神秘面纱。

为了证明开发人员可以抛开其有形的基础结构这条“安全毛毯”并将其应用程序引擎置于云中,我们将介绍如何实现电子商务应用程序的一个小型子集 Hollywood Hackers,您可以从中购买到 Hollywood 用于完全忽略物理法则和过时的常识的所有神奇技术。

我们将介绍的两个主要方案如下:

将异步文本消息 (“toasts”) 发送给使用该应用程序的用户,以通知他们发生的重要事件(如已提交他们的购物车)或在员工之间发送消息。此方案使用 Windows Azure Queue、Windows Azure Table 和 Windows Azure 工作者角色。

此方案使用 Windows Azure Queue 和 Windows Azure 工作者角色将购物车提交给执行引擎。

使用队列存储进行内部应用程序消息传送

在介绍具体的方案之前,我们需要先介绍一些有关 Windows Azure Queue 的基础知识。云中的队列与传统的 .NET 应用程序中的队列的运行方式不太一样。在处理 AppDomain 中的数据时,您知道该数据只有一份,它完整地位于单一托管进程中。

而在云中,您的一部分数据可能在加利福尼亚,而另一部分可能在纽约,并且您可能会安排一个工作者角色在德克萨斯州对该数据进行处理,而另一工作者角色在北达科他州进行数据处理。

很多开发人员在适应这种分布式计算和分布式数据时面临着一些不熟悉的问题,例如对可能出现的故障进行编码、针对数据提交形成多次重试的概念甚至幂等性的理念。

只要您不将 Windows Azure Queue 视为进程内的常规 CLR 队列,其工作方式其实非常简单。首先,应用程序将向队列获取一些数量的消息(需要记住,一次不会超过 20 条)并提供一个超时。此超时控制对其他队列处理客户端隐藏这些消息的时间。当应用程序成功完成需要对队列消息进行的所有处理后,将删除该消息。

如果应用程序引发异常或处理队列消息失败,则在超时期限过后,其他客户端可以再次看到该消息。因此,当一个工作者角色处理失败后,其他工作者角色可以继续进行处理。向队列提交消息非常简单:应用程序直接或借助客户端库形成适当的 HTTP POST 消息,然后提交字符串或字节数组。队列专门用于进行内部应用程序消息传送和非永久存储,因此这些消息占用的空间需要相当小。

如上所述,您可能安排多个工作者角色都尝试处理同一消息。虽然隐藏当前正在处理的消息的不可见超时很有帮助,但不能确保万无一失。要完全避免冲突,您应该将您的引擎处理设计为幂等。换句话说,同一队列消息应该可以由一个或多个工作者角色处理多次,而不会使应用程序处于不一致的状态。

理想情况下,您希望工作者角色可以检测出是否已完成对给定消息的处理。在编写工作者角色来处理队列消息时,请牢记您的代码可能会尝试处理已处理过的消息,尽管这个可能性微乎其微。

图 1 中的代码段显示了如何使用随 Windows Azure SDK 一起提供的 StorageClient 程序集创建消息并将其提交给 Windows Azure Queue。StorageClient 库实际上只是 Windows Azure Storage HTTP 接口周围的包装。

 图 1 创建消息并将其提交给 Windows Azure Queue

string accountName; 
string accountSharedKey; 
string queueBaseUri; 
string StorageCredentialsAccountAndKey credentials; 
 
if (RoleEnvironment.IsAvailable) 
{ 
// We are running in a cloud - INCLUDING LOCAL! 
 accountName = 
 RoleEnvironment.GetConfigurationSettingValue(AccountName); 
 accountSharedKey =  
 RoleEnvironment.GetConfigurationSettingValue(AccountSharedKey); 
 queueBaseUri = RoleEnvironment.GetConfigurationSettingValue 
 (QueueStorageEndpoint); 
} 
else 
{ 
 accountName = ConfigurationManager.AppSettings[AccountName]; 
 accountSharedKey = 
 ConfigurationManager.AppSettings[AccountSharedKey]; 
 queueBaseUri = 
 ConfigurationManager.AppSettings[QueueStorageEndpoint]; 
} 
credentials = 
new StorageCredentialsAccountAndKey(accountName, accountSharedKey); 
CloudQueueClient client = 
new CloudQueueClient(queueBaseUri, credentials); 
CloudQueue queue = client.GetQueueReference(queueName); 
CloudQueueMessage m = new CloudQueueMessage( 
 /* string or byte[] representing message to enqueue */); 
Queue.AddMessage(m);

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top