Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
本文是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程序如何读取并处理信息。
步骤二:添加SDK程序集引用
请在项目属性页里确认项目的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程序就可以跨越机器进行通信了。
Anonymous
March 08, 2010
有没有适合其他语言的啊?我在网上没找着Anonymous
March 08, 2010
>xiao_jing said: >有没有适合其他语言的啊?我在网上没找着 你好,出于篇幅考虑我们只使用C#语言。请问你要使用什么语言?如果是VB.NET的话可以使用一些工具来转换,比如: http://www.developerfusion.com/tools/convert/csharp-to-vb/ 目前为止的代码都比较简单的。之后复杂一些的代码我们考虑会放到http://1code.codeplex.com/ 提供大家下载。会包括C#和VB.NET的。 如果是Java,C++或者其他语言的话需要自己写发送HTTP请求的代码。我们之后会给出教学说明在.NET中如何手动调用REST API。其他语言也可以参考教学中的代码逻辑,大致上是一样的。Anonymous
July 20, 2010
hi can you tell me the capacity of queue? thank youAnonymous
March 07, 2011
我按上述操作运行时 在queue.CreateIfNotExist() 上报错: Server encountered an internal error. Please try again after some time. 请问这是什么原因引起的?谢谢Anonymous
October 16, 2011
queue.GetMessage在Queue中没有消息时,不会阻塞,也不能注册回调,而是反复轮训,比较令人遗憾。