本文是 Windows Azure 入门教学 的第五篇文章。
本文将会介绍如何使用 Queue Storage。 Queue Storage提供给我们一个云端的队列。我们可以用 Queue Storage来进行进程间的相互通信(包括运行在不同机器上的进程之间的通信)。
一个使用 Queue Storage经典的场景是,在一个 Web应用程序中,用户通过表单递交给服务器数据,服务器收到数据后将进行处理,而这一处理将花费很多时间。这种情况下,服务器端通过 Queue Storage可以把用户递交的信息存储在队列中,后台再运行一个程序从队列中取得数据进行信息的处理。
以往如果程序时运行在 Windows操作系统上,那么我们可以使用MSMQ来做类似的工作。而 Queue Storage的出现为我们提供了另一种选择。特别是在非 Windows操作系统上,我们依然可以使用 Queue Storage的REST API来很方便地使用它。
有关 Queue Storage REST API的详细信息,请参见Queue 服务 API。
为了方便 .NET开发人员,我们在 SDK中提供了 Microsoft.WindowsAzure.StorageClient类来帮助发送 REST请求。
在开始本教学之前,请确保你从Windows Azure 平台下载 下载并安装了最新的 Windows Azure开发工具。 本教学使用 Visual Studio 2010作为开发工具。
由于我们要在本地模拟环境下测试 Queue Storage,首先,请确保 Storage Emulator已经启动。我们可以找到管理器的进程手动启动或者让 Visual Studio 2010帮助我们启动他。
右击工具栏中 Windows Azure模拟器的图标,选择” Show Storage Emulator UI”。弹出如下图所示的窗口:
我们要关注的是 Service management中 Queue所在的一行。要确保 Status为 Running。
确认完毕后启动 Visual Studio 2010,并且新建两个 Console项目。我们将演示如何在一个 Console程序中往 Queue Storage中添加信息然后另外一个 Console程序如何读取并处理信息。
请在项目属性页里确认项目的 Target framework的值是 .NET Framework 4或 .NET Framework 3.5。然后在两个 Console项目中均添加 C:/Program Files/Windows Azure SDK/v1.3/ref/Microsoft.WindowsAzure.StorageClient.dll的引用。该路径为 SDK默认安装路径,如果你不能在这个路径中找到 Microsoft.WindowsAzure.StorageClient.dll请从 SDK安装路径中寻找。
首先在两个项目中的 Program.cs中均引用命名空间:
using System.Threading; using Microsoft.WindowsAzure; using Microsoft.WindowsAzure.StorageClient;然后在其中一个项目(为了叙述方便,后面称之为 Client项目)的 Main方法中加入如下代码,我们将用它来向 Queue Storage中添加信息。
static void Main(string [] args) { var storageAccount = CloudStorageAccount .DevelopmentStorageAccount; var queueStorage = storageAccount.CreateCloudQueueClient(); // 检查名为 helloworldqueue 的队列是否被创建,如果没有,创建它 var queue = queueStorage.GetQueueReference("helloworldqueue" ); queue.CreateIfNotExist(); Console .WriteLine("Client is running..." ); while (true ) { // 插入数据到队列中 queue.AddMessage(new CloudQueueMessage (string .Format("client sent information: {0}" , DateTime .UtcNow.ToString()))); // 每次插入数据后线程休息 3 秒 Thread .Sleep(3000); } }接着在另外一个项目(为了叙述方便,后面称之为 Server项目)的 Main方法中加入如下代码,我们将用它来从 Queue Storage中读取信息和进行处理。
static void Main(string [] args) { var storageAccount = CloudStorageAccount .DevelopmentStorageAccount; var queueStorage = storageAccount.CreateCloudQueueClient(); // 检查名为 helloworldqueue 的队列是否被创建,如果没有,创建它 var queue = queueStorage.GetQueueReference("helloworldqueue" ); queue.CreateIfNotExist(); Console .WriteLine("Server is running..." ); while (true ) { // 从队列中读取一条信息 // 收到信息后可以根据收到的信息做处理,为了演示方便我们这里只是把信息显示出来 // 在云端发送消息后这条消息将对于后续的请求不可见,但是并未被删除。我们需要显示删除它。 // 否则在一段时间后该消息将重新可见。这一设计的好处是确保了所有消息都能够被处理。 // 如果程序在收到消息后处理消息前就异常终止了那么数据依然在一段时间后可以被重新处理。 // 详情请参考 MSDN 文档 var message = queue.GetMessage(); if (message != null ) { Console .WriteLine(string .Format("Message retrieved: {0}" , message.AsString)); // 处理完数据后必须显示删除消息 queue.DeleteMessage(message); } // 每次读取数据后线程休息 3 秒 Thread .Sleep(3000); } }
步骤三中的代码中,首先我们通过 CloudStorageAccount.DevelopmentStorageAccount来说明我们使用的本地的 Development Storage自带账户而不是真正的云端存储服务账户。 (如果要用真实账户可以使用
// DefaultEndpointsProtocol=https 可以改成 DefaultEndpointsProtocol=http 表示用 HTTP 而不是 HTTPS CloudStorageAccount .Parse("DefaultEndpointsProtocol=https;AccountName=[ 用户名 ];AccountKey=[ 密码 ]" );
来实例化对象 )然后通过该账户类来实例化一个 Queue客户端类。这两步是使用 SDK中 StorageClient程序集来调用 Queue Storage服务的必要步骤。
Client项目中的代码相对简单。大约每隔 3秒向 Queue Storage中插入一条数据。 Server端的项目中我们则大约每隔 3秒从 Queue Storage中读取一条数据。处理完毕后将之删除。对于为什么必须在读取后显示删除的问题请参考注释部分。
先运行 Client程序然后运行 Server个程序。如果一切正常,你将会看到 Server项目的 Console程序输出收到的消息:
注意由于是本地模拟, Client和 Server程序需要要在同一台机器上运行。但是如果使用真实账户的话, Client和 Server程序就可以跨越机器进行通信了。