zoukankan      html  css  js  c++  java
  • Azure 基础:Queue Storage

    Azure Storage 是微软 Azure 云提供的云端存储解决方案,当前支持的存储类型有 Blob、Queue、File 和 Table。

    笔者在前文中介绍了 File Storage 的基本用法,本文将介绍 Queue Storage 的主要使用方法。

    Queue Storage 是什么?

    Azure Queue Storage 是一个存储大量消息的存储服务,这些消息可以在任何地方通过 HTTP/HTTPS 访问。每条消息最大 64K,消息的数据量几乎不受限制 (除非超出了您的 Storage Account 的总容量) 。

    下面是 Queue Storage 典型的应用场景:
    1.    创建未处理任务的队列,以便异步的处理这些任务。
    2.    把消息从 web role 传递给 worker role 进行处理。

    Azure Queue Storage的结构

    下图描述了 Queue Storage 的基本组织结构:

    Azure Storage Account:

    Storage Account 是用来管理 Azure Storage 的一个命名空间,主要用来控制存储数据的访问权限和计费。对 Blob、Queue、File 和 Table 这些 Azure 提供的存储服务的访问控制都是通过 Storage Account 来进行的,所以要想使用 Queue Storage,需要先创建你的 Storage Account。

    Queue:

    每个 Queue 都是一组消息的集合。每一条消息都必须属于一个 Queue。Queue 名称中的字符必须是小写。

    Message:

    每条 Message 的最大长度为 64KB,Message 在 Queue 中停留的最长时间为 7 天。

    URL format:

    Queue 的 URL 地址格式为:

    http://<storage account>.queue.core.windows.net/<queuename>

    下面是个更真实的例子:

    http://nickstorage.queue.core.windows.net/app1tasks

    如果您还不熟悉 Azure Storage Account 的使用,以及如何通过 WindowsAzure.Storage 库访问 Azure Storage,请参考前文《Azure Table storage 基本用法》中的介绍,这里就不重复了。

    为了方便查看 C# 代码执行的结果,本文使用了 MS 发布的一个 Azure Storage 客户端工具:Microsoft Azure Storage Explorer,文中简称为 Storage Explorer。下面是 Queue Storage 的一个截图:

    接下来我们通过 C# 代码来介绍如何操作 Queue Storage。

    创建 Queue

    我们先来创建一个名为 "app2tasks" 的 Queue:

    // CloudStorageAccount 类表示一个 Azure Storage Account,我们需要先创建它的实例,才能访问属于它的资源。
    // 注意连接字符串中的xxx和yyy,分别对应Access keys中的Storage account name 和 key。
    CloudStorageAccount storageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=xxx;AccountKey=yyy");
    
    // CloudQueueClient 类是 Windows Azure Queue Service 客户端的逻辑表示,我们需要使用它来配置和执行对 Queue Storage 的操作。
    CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
    // CloudQueue 表示一个 Queue 对象, 绝大多数的操作都是通过这个对象完成的。
    CloudQueue queue = queueClient.GetQueueReference("app2tasks");
    // 如果不存在就创建名称为 "app2tasks" 的 Queue。
    queue.CreateIfNotExists();

    执行上面的代码,然后在 Storage Explorer 中查看结果:

    把消息插入 Queue

    现实的应用场景中肯定有一个或多个程序产生 Message 并插入到 Queue 中,接下来我们看看用 C# 如何实现:

    string current = DateTime.Now.ToString();
    // 把消息插入到队列中。
    CloudQueueMessage message = new CloudQueueMessage("Hello, World. -- " + current);
    queue.AddMessage(message)

    调用几次上面的代码看看结果如何:

    我通过三次调用向 Queue 中加入了三条消息,请注意插入它们的时间,分别是 11:33:45,11:33:57,和 11.34:16。在接下来的描述中我分别称它们为第一条消息、第二条消息和第三条消息。

    查看 Queue 中的消息

    既然是队列,肯定有队头和队尾,消息从队头出队从队尾入队。那么能不能查看一下队头的消息 (也就是下一条要处理的消息,此处只是查看并不是要处理) 呢?当然可以:

    // 总是取到队头的消息,没有消息出队。
    // 消息在队列中的位置、可见状态也没有发生变化。 
    CloudQueueMessage peekedMessage = queue.PeekMessage();

    PeekMessage 方法总是取到处于队头位置的那条消息,并且不改变队列的状态!

    为了帮助小伙伴们更深刻地理解 PeekMessage 方法的内涵,笔者从网上找了一张解释 peek 一词的图片,请注意图片中的黄色线条:

    (本图片来自于互联网,如有版权问题请与笔者联系。)

    查看 Queue 的长度

    经常的查看 Queue 的长度是个不错的注意,因为你需要避免一些由于 Queue 过长带来的问题:

    // 获取 Queue 的属性。
    queue.FetchAttributes();
    int? cachedMessageCount = queue.ApproximateMessageCount;

    更新 Queue 中的消息

    如果一条消息已经被添加到 Queue 中了,但是又需要更新其内容该怎么办?我们可以找到这条消息然后更新它的内容:

    CloudQueueMessage message = queue.GetMessage();
    // 执行 getmessage(), 队头的消息会变得不可见。
    message.SetMessageContent("Updated contents.");
    queue.UpdateMessage(message,
        TimeSpan.FromSeconds(60.0), 
        MessageUpdateFields.Content | MessageUpdateFields.Visibility);
    // 更新完消息内容的60s 之后,该消息会重新可见,但是是在队尾。

    执行上面的代码后,我们发现在 Storage Explorer 中"第一条消息"不见了。过了 60 秒之后它又重新出现在 Storage Explorer 中,但是它的内容已经变化,位置也成了队尾:

    此时我们也只能通过 ID 认出它是之前的"第一条消息",之前"第二条消息","第三条消息"的位置也发生了相应的变化。

    处理 Queue 中的消息

    如何处理 Queue 中的消息呢?我们的程序大体应该遵循下面的逻辑:
    使用 GetMessage 方法取出队头的消息,此时该消息会在 Queue 中 30 秒不可见(这个时常用户可以设置,默认是 30 秒);
    处理消息;
    正常处理完成后,调用 Delete 方法删除消息;
    如果没有正常处理消息 (没有调用 Delete 方法),此消息会在 30 秒后重新出现在队尾。
    类似于下面的代码逻辑:

    // 执行 getmessage(), 队头的消息会变得不可见。
    CloudQueueMessage message = queue.GetMessage();
    try
    {
        //处理消息
        // 如果在30s内你没有删除这条消息,它会重新出现在队尾。
        // 所以正确处理一条消息的过程是,处理完成后,删除这条消息
        queue.DeleteMessage(message);
    }
    catch //(消息处理异常)
    { }

    删除 Queue 中的消息

    除了正常处理完消息后把消息从队列中删除,我们也可以找到一条消息,直接删除它。本质上和处理完再删除是一样的。

    总结

    Queue Storage 为应用之间的解耦提供了很好的解决方式。使得消息的产生者和消息的处理者可以互相不知道彼此的存在。为我们处理这类问题添加了一件有力的武器。

  • 相关阅读:
    使用 asp.net mvc和 jQuery UI 控件包
    ServiceStack.Redis 使用教程
    HTC T8878刷机手册
    Entity Framework CodeFirst 文章汇集
    2011年Mono发展历程
    日志管理实用程序LogExpert
    使用 NuGet 管理项目库
    WCF 4.0路由服务Routing Service
    精进不休 .NET 4.0 (1) asp.net 4.0 新特性之web.config的改进, ViewStateMode, ClientIDMode, EnablePersistedSelection, 控件的其它一些改进
    精进不休 .NET 4.0 (7) ADO.NET Entity Framework 4.0 新特性
  • 原文地址:https://www.cnblogs.com/sparkdev/p/6505431.html
Copyright © 2011-2022 走看看