Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

时间:2023-03-09 03:17:26
Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

  《Windows Azure Platform 系列文章目录

  本章DEMO部分源代码,请在这里下载。

  在上一章中,笔者介绍了我们可以使用Azure PaaS的Web Role和Worker Role来处理复杂的业务逻辑

  -Web Role可以快速响应前端的业务请求,并将输入保存到Azure Storage Queue中

  -Worker Role将数据从Queue中读取,可以在后端处理复杂的业务逻辑

  -可以看到,Azure Storage Queue是前端业务逻辑和后端业务处理的桥梁

  该架构图可以用下图表示:

  Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

  有关Azure Storage Queue的知识,可以参考Windows Azure Storage (1) Windows Azure Storage Service存储服务

  

  接下来,我们模拟一个场景:

  1.前端用户通过Web Role的Asp.NET页面,将输入框的内容增加到Azure Storage Queue中

  2.后端的Worker Role,通过WorkerRole.cs中的Run()函数,从Azure Storage Queue中拿到消息内容,进行输入。处理完毕后,将该消息删除。

  注意:本章内容中,Web Role只响应前端的页面请求。Worker Role在后端处理复杂的业务处理。

  Web Role和Worker Role是计算分离的(注意是计算分离,不是多线程)。

  因为Web Role和Worker Role是部署在不同的计算节点上。不会因为用户访问Web Role,造成CPU压力过高而影响Worker Role。

  以下是源代码讲解部分:

  1.首先,我们创建一个新的cloud project,重命名为AzureWorkerRole。图略:

  2.在项目文件中,添加Web Role和Worker Role。如下图:

  Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

  模板我们选择Web Form。图略。

  3.在WebRole1中,增加Default.aspx页面,添加TextBox和Button控件。增加以下代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Microsoft.WindowsAzure.ServiceRuntime;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Queue; namespace WebRole1
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{ } protected void btnSubmit_Click(object sender, EventArgs e)
{
AddMessage(txbInput.Text.Trim());
txbInput.Text = "";
}
/// <summary>
/// 将消息加入到Azure Storage Queue
/// </summary>
/// <param name="inputMessage"></param>
private void AddMessage(string inputMessage)
{
var account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("StorageConnection"));
var queueClient = account.CreateCloudQueueClient();
var queue = queueClient.GetQueueReference("taskqueue"); queue.CreateIfNotExists(); CloudQueueMessage message = new CloudQueueMessage(inputMessage);
queue.AddMessage(message);
}
}
}

  核心代码为queue.AddMessage()。将消息内容增加到Azure Storage Queue中。

  4.在WorkerRole.cs增加以下代码:

  /// <summary>
/// Editor: Lei Zhang
/// Create Azure Storage Queue
/// </summary>
private void CreateAzureStorageQueue()
{
var account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("StorageConnection"));
var queueClient = account.CreateCloudQueueClient(); //Azure Storage Queue名称必须为小写
var queue = queueClient.GetQueueReference("taskqueue");
queue.CreateIfNotExists();
} /// <summary>
/// 从Azure Storage Queue中读取数据
/// </summary>
private void GetQueue()
{
var account = CloudStorageAccount.Parse(RoleEnvironment.GetConfigurationSettingValue("StorageConnection"));
var queueClient = account.CreateCloudQueueClient(); //Azure Storage Queue名称必须为小写
var queue = queueClient.GetQueueReference("taskqueue");
queue.CreateIfNotExists(); // dequeue the message and lock message in 30 seconds
CloudQueueMessage retrievedMessage = queue.GetMessage(TimeSpan.FromSeconds());
if (retrievedMessage == null) return; Trace.TraceInformation("Retrieved message with content '{0}'", retrievedMessage.AsString); // Async delete the message
queue.DeleteMessage(retrievedMessage);
Trace.TraceInformation("Deleted message");
}

  Worker Role的核心代码为上面的queue.GetMessage(TimeSpan.FromSeconds(30))和 queue.DeleteMessage()。

  当有多个Worker Role的情况下,某个Worker Role Instance使用queue.GetMessage(TimeSpan.FromSeconds(30))读取到Queue Message的时候,默认会在这个消息上加一个锁,时间间隔为30秒。

  在30秒内,其他Worker Role Instance不会读取到这个Message,以防止Message被重复读取。

  Message被读取到并处理完毕后,记得用DeleteMessage删除该消息

  

  我们还可以通过以下API,批量读取20条消息(Queue Message),最多读取32个消息。同时将读取每一条消息的锁设置为5分钟

foreach (CloudQueueMessage message in queue.GetMessages(, TimeSpan.FromMinutes()))
{
// Process all messages in less than 5 minutes, deleting each message after processing.
queue.DeleteMessage(message);
}

  

  5.最后我们在Web Role和Worker Role的Settings,增加相应的Azure Storage Connection String连接字符串。

  Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

  6.我们在本地,通过Visual Studio 2013运行程序。在Default.aspx页面中输入消息内容,如下:

  Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

  7.然后我们打开本地模拟器,可以看到Worker Role的输出。

  Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

  

  8.我们重复在Default.aspx页面中输入多个值。在本地模拟器,可以看到Worker Role的多个输出。

  Windows Azure Cloud Service (12) PaaS之Web Role, Worker Role, Azure Storage Queue(下)

  

  9.我们可以在WorkerRole.cs的代码中,还可以异步处理其他复杂的业务逻辑,比如异步发送邮件,异步处理数据等等。