.Net 中的 Azure Queue Storage 的应用

  Azure Queue Storage 是一个存储大量消息的队列存储服务。工作中,我们有时会遇到这么样的需求,当某个业务操作触发一个事件,而后让另一个系统对触发的这个事件进行处理,那么,这里的话可以采用配置一个 hook ,将截取到的这个消息存储到这个 Queues 消息队列里面,而后另一个系统可以采用新进新出的规则取获取这个消息,通过消息内容中的数据做出一系列的操作,而后删除这个消息。
业务系统Ⅰ 消息队列 业务系统Ⅱ 消息 n Hook 消息 3 消息 2 消息 1 · · ·

项目准备

创建项目

  还是在这个 GitHub 中项目(AzureStorageConsoleDemo)里面新建一个 AzureQueueDemo 文件夹,在文件夹中创建类文件 StorageQueuesHelp.cs,安装 NuGet 包 Azure.Storage.Queues
解决方案管理器

StorageQueuesHelp 获取链接字符串

  在 StorageQueuesHelp.cs 中键入如下代码以获取配置文件连接字符串。

using Azure.Storage.Queues;
using Microsoft.Extensions.Configuration;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace AzureStorageConsoleDemo.AzureQueueDemo
{
    class StorageQueuesHelp
    {
        /// <summary>
        /// Storage 连接字符串
        /// </summary>
        public string StorageConnectionString { get; set; }

        /// <summary>
        /// 初始化程序配置文件
        /// </summary>
        /// <returns>StorageTableHelp</returns>
        public static StorageQueuesHelp LoadAppSettings()
        {
            IConfigurationRoot configRoot = new ConfigurationBuilder().AddJsonFile("Settings.json").Build();
            StorageQueuesHelp appSettings = configRoot.Get<StorageQueuesHelp>();
            return appSettings;
        }
    }
}

Queues 操作

  关于 Queue 的应用操作有很多,这里根据常用的几类进行总结如下。

创建队列

  这里创建一个 Queues ,返回的是一个 QueueClient ,可以通过 QueueClient 对消息队列的进一步操作,如 CRUD 等。在 StorageQueuesHelp.cs 中键入如下代码以获取配置文件连接字符串。

/// <summary>
/// 创建一个 Queues
/// </summary>
/// <param name="queuesName">Queues 的名称</param>
/// <returns>QueueClient</returns>
public static async Task<QueueClient> CreateQueueClientAsync(string queuesName)
{
    string connectionString = LoadAppSettings().StorageConnectionString;
    QueueClient queueClient = new QueueClient(connectionString, queuesName);
    await queueClient.CreateAsync();
    return queueClient;
}

  使用示例:

static async Task Main(string[] args)
{
	// 声明一个 Queues 的名称
    string queueName = "queues" + Guid.NewGuid().ToString().Substring(0, 5);
    // 传入一个 Queues 的名称 返回 QueueClient  通过 QueueClient 可以对 Queues 进行操作
    QueueClient queueClient1 = await StorageQueuesHelp.CreateQueueClientAsync(queueName);
}

向队列中添加消息

  在 StorageQueuesHelp.cs 中键入如下代码以获取配置文件连接字符串。

/// <summary>
/// 向队列中插入一条消息 默认永不过期
/// </summary>
/// <param name="theQueue">QueueClient</param>
/// <param name="newMessage">消息字符串</param>
/// <returns></returns>
public static async Task<SendReceipt> InsertMessageAsync(QueueClient theQueue, string newMessage, bool isInvalid = false)
{
    // 检测队列是否创建,如果没有创建则创建,否则不做操作
    await theQueue.CreateIfNotExistsAsync();
    // 向队列发送一条新的消息
    SendReceipt sendReceipt;
    if (isInvalid)
    {
        // 默认生存周期为 7 天
        sendReceipt = await theQueue.SendMessageAsync(newMessage);
    }
    else
    {
        // 永不过期消息
        sendReceipt = await theQueue.SendMessageAsync(newMessage, default, TimeSpan.FromSeconds(-1), default);
    }
    return sendReceipt;
}

  使用示例:

static async Task Main(string[] args)
{
	// 声明一个 Queues 的名称
    string queueName = "queues" + Guid.NewGuid().ToString().Substring(0, 5);
    // 传入一个 Queues 的名称 返回 QueueClient  通过 QueueClient 可以对 Queues 进行操作
    QueueClient queueClient = await StorageQueuesHelp.CreateQueueClientAsync(queueName);
    // 插入一条消息到队列中
    SendReceipt sendReceipt = await StorageQueuesHelp.InsertMessageAsync(queueClient,"一条消息",true);
}

更新队列中的消息

  如果需要更新队列中的一条消息,可以使用 queueClient.UpdateMessageAsync() 方法来处理,使用方式如下所示。

static async Task Main(string[] args)
{
	// 声明一个 Queues 的名称
    string queueName = "queues" + Guid.NewGuid().ToString().Substring(0, 5);
    // 传入一个 Queues 的名称 返回 QueueClient  通过 QueueClient 可以对 Queues 进行操作
    QueueClient queueClient = await StorageQueuesHelp.CreateQueueClientAsync(queueName);
    // 插入一条消息到队列中
    SendReceipt sendReceipt = await StorageQueuesHelp.InsertMessageAsync(queueClient,"第一条消息",true);
    // 更新刚刚插入成功的一条消息
    await queueClient.UpdateMessageAsync(sendReceipt.MessageId, sendReceipt.PopReceipt, "第一条消息已更新");
}

查看队列中的消息

  即查看队列中的消息,但 所被查看的消息依旧存在于队列之中 。示例代码如下所示。

static async Task Main(string[] args)
{
	// 声明一个 Queues 的名称
    string queueName = "queues" + Guid.NewGuid().ToString().Substring(0, 5);
    // 传入一个 Queues 的名称 返回 QueueClient  通过 QueueClient 可以对 Queues 进行操作
    QueueClient queueClient = await StorageQueuesHelp.CreateQueueClientAsync(queueName);
    // 查看队列中的消息 PeekMessagesAsync()中的参数为最大为 32 ,如果不设置参数,那么就取队列中的第一个消息
	PeekedMessage[] peekedMessages = await queueClient.PeekMessagesAsync(maxMessages: 10);
	//遍历获取的消息
	foreach (PeekedMessage peekedMessage in peekedMessages)
	{
	    // 显示消息
	    Console.WriteLine($"消息: {peekedMessage.MessageText}");
	}
}

获取队列中的消息

  和查看队列中的消息类似,但 所被查看的消息将会在默认超时时间内在队列中不可见1 。示例代码如下所示。

static async Task Main(string[] args)
{
	// 声明一个 Queues 的名称
    string queueName = "queues" + Guid.NewGuid().ToString().Substring(0, 5);
    // 传入一个 Queues 的名称 返回 QueueClient  通过 QueueClient 可以对 Queues 进行操作
    QueueClient queueClient = await StorageQueuesHelp.CreateQueueClientAsync(queueName);
    // 从队列中获取一条小溪消息 获取的消息将会在队列中 30 秒不可见
	QueueMessage[] message = await queueClient.ReceiveMessagesAsync();
	Console.WriteLine($"消息: {message[0].MessageText}");
	// 从队列中获取最多 10 条消息 获取的消息将会在队列中 30 秒不可见
	QueueMessage[] messages = await queueClient.ReceiveMessagesAsync(maxMessages: 10);
	foreach (var peekedMessage in messages)
	{
	    Console.WriteLine($"消息: {peekedMessage.MessageText}");
	}
}

从队列中删除消息

  当从队列中获取一条消息后,需要对这条消息进行一系列程序操作,等操作完毕之后,需要将这条消息从队列中删除,这里可以通过调用 DeleteMessageAsync 从队列中删除该消息。

static async Task Main(string[] args)
{
	// 声明一个 Queues 的名称
    string queueName = "queues" + Guid.NewGuid().ToString().Substring(0, 5);
    // 传入一个 Queues 的名称 返回 QueueClient  通过 QueueClient 可以对 Queues 进行操作
    QueueClient queueClient = await StorageQueuesHelp.CreateQueueClientAsync(queueName);
    // 从队列中获取一条小溪消息 获取的消息将会在队列中 30 秒不可见
	QueueMessage[] message = await queueClient.ReceiveMessagesAsync();
	// 删除从队列中检索出来的这条消息
    await queueClient.DeleteMessageAsync(message[0].MessageId, message[0].PopReceipt);
}

情景回顾:
  记得工作中有一次我拿到一个项目,需要获取一个消息,而后对这个消息经过操作处理后再删除,否则在处理下一个消息的时候还会重复获取这条消息。于是这个项目在获取这条消息之后,在处理这条消息之前直接就将这条消息给删除掉了,于是,这么就会出现一种情况,程序在处理这条消息的时候并未成功处理这条消息,但是这条消息却被从队列中删除掉了,那么,怎么办呢?
建议提示:
  像这种情况,大部分程序员都会想到,我可以在操作处理这条消息成功过后再删除这条消息呀!对的,没错,这样能够解决这个问题。但是还有一个问题,如果让程序在操作处理消息之后再进行删除消息操作,那么当每一次获取这条消息都不能成功处理这条消息,而程序继续获取这条消息,是不是程序就是锁在这条消息处而不能继续运行下一条消息了呢?
  其实,可以调用 DequeueCount 来获取这条消息出队列多少次了,当程序重复处理这条消息重复达到多少次以后我们可以直接将这条消息删除掉并报错处理,让程序员工程师对这条消息进行单独操作。如下示例所示:
  long msgCount=message[0].DequeueCount; // 获取这条消息出队列次数

删除队列

  为了节约账户所花费的成本,空队列可以选择删除,在需要的时候再创建即可,但是切记在删除之前还是需要跟你的客户或者老板沟通好,是否确定要删除这个队列哦。

static async Task Main(string[] args)
{
    string queueName = "queues" + Guid.NewGuid().ToString().Substring(0, 5);
    QueueClient queueClient = await StorageQueuesHelp.CreateQueueClientAsync(queueName);
    // 删除这个队列
    Console.WriteLine($"删除队列: {queueClient.Name}");
    await queueClient.DeleteAsync();
    Console.ReadLine();
}

The Ended

  如果你还想要领略一下 Azure Queue Storage 的那些花式操作,你可以访问微软的 官方教程 。我这里总结的就这些,因为工作中就这么用的,喜欢的可以 点各赞、收个藏


  1. 指定相对于服务器时间的新可见性超时值(以秒为单位)。 默认值为 30 秒。 ↩︎

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值