Руководство по Работа с очередями Хранилища очередей Azure в .NET

Хранилище очередей Azure реализует облачный механизм очередей для поддержки взаимодействия между компонентами распределенного приложения. Каждая очередь отслеживает список сообщений, которые добавляются компонентом отправителя и обрабатываются компонентом получателя. Очередь позволяет мгновенно масштабировать приложение при любом изменении нагрузки. В этой статье описаны основные процессы работы с очередью Хранилища очередей Azure.

В этом руководстве описано следующее:

  • Создание учетной записи хранения Azure
  • Создайте приложение
  • Добавление клиентских библиотек Azure
  • Добавление поддержки для асинхронных вызовов
  • Создание очереди
  • Вставка сообщения в очередь
  • Вывод сообщений из очереди
  • Удаление пустой очереди
  • Проверка аргументов командной строки
  • Создание и запуск приложения

Предварительные требования

Создание учетной записи хранения Azure

Прежде всего создайте учетную запись хранения Azure. Пошаговые инструкции по созданию учетной записи хранения см. в статье Создание учетной записи хранения. Это отдельный шаг, который вы выполняете после создания бесплатной учетной записи Azure для выполнения предварительных требований.

Создайте приложение

Создайте приложение .NET Core с именем QueueApp. Для простоты одно приложение будет отправлять сообщения в очередь и принимать их.

  1. В окне консоли (cmd, PowerShell или Azure CLI) выполните команду dotnet new, чтобы создать консольное приложение с именем QueueApp. Эта команда создает простой проект Hello World на языке C# с одним файлом исходного кода: Program.cs.

    dotnet new console -n QueueApp
    
  2. Перейдите в созданную папку QueueApp и создайте приложение, чтобы убедиться, что все в порядке.

    cd QueueApp
    
    dotnet build
    

    Должен отобразиться похожий результат:

    C:\Tutorials>dotnet new console -n QueueApp
    The template "Console Application" was created successfully.
    
    Processing post-creation actions...
    Running 'dotnet restore' on QueueApp\QueueApp.csproj...
      Restore completed in 155.63 ms for C:\Tutorials\QueueApp\QueueApp.csproj.
    
    Restore succeeded.
    
    C:\Tutorials>cd QueueApp
    
    C:\Tutorials\QueueApp>dotnet build
    Microsoft (R) Build Engine version 16.0.450+ga8dc7f1d34 for .NET Core
    Copyright (C) Microsoft Corporation. All rights reserved.
    
      Restore completed in 40.87 ms for C:\Tutorials\QueueApp\QueueApp.csproj.
      QueueApp -> C:\Tutorials\QueueApp\bin\Debug\netcoreapp3.1\QueueApp.dll
    
    Build succeeded.
        0 Warning(s)
        0 Error(s)
    
    Time Elapsed 00:00:02.40
    
    C:\Tutorials\QueueApp>_
    

Добавление клиентских библиотек Azure

  1. Добавьте клиентские библиотеки службы хранилища Azure в проект с помощью команды dotnet add package.

    Выполните следующую команду из папки проекта в окне консоли.

    dotnet add package Azure.Storage.Queues
    

Добавление инструкций using

  1. Перейдите в каталог проекта и введите в командной строке code ., чтобы открыть Visual Studio Code в этом каталоге. Оставьте окно командной строки открытым. Позднее нам нужно будет выполнить здесь другие команды. Если появится предложение добавить необходимые для сборки и отладки ресурсы C#, нажмите кнопку Да.

  2. Откройте файл исходного кода Program.cs и добавьте следующие пространства имен сразу за инструкцией using System;. Это приложение использует типы из добавленных пространств имен, чтобы подключаться к службе хранилища Azure и работать с очередями.

    using System.Threading.Tasks;
    using Azure.Storage.Queues;
    using Azure.Storage.Queues.Models;
    
  3. Сохраните файл Program.cs.

Добавление поддержки для асинхронных вызовов

Так как приложение использует облачные ресурсы, код выполняется асинхронно.

  1. Обновите метод Main, чтобы он выполнялся асинхронно. Замените void возвращаемым значением async Task.

    static async Task Main(string[] args)
    
  2. Сохраните файл Program.cs.

Создание очереди

Перед выполнением вызовов к Azure API необходимо получить учетные данные с портала Azure.

Копирование учетных данных с портала Azure

Когда пример приложения выполняет запрос к службе хранилища Azure, он должен быть авторизован. Для авторизации запроса добавьте в приложение учетные данные учетной записи хранения в виде строки подключения. Чтобы просмотреть учетные данные учетной записи хранения, выполните следующие шаги:

  1. Войдите на портал Azure.

  2. Перейдите к учетной записи хранения.

  3. На панели меню учетной записи хранения в разделе Безопасность и сети выберите Ключи доступа. На этой странице вы увидите ключи доступа к учетной записи и полную строку подключения для каждого ключа.

    Снимок экрана: местоположение параметров ключа доступа в портал Azure

  4. В области Ключи доступа выберите команду Показать ключи.

  5. В разделе key1 выберите значение Строка подключения. Нажмите значок Копировать в буфер обмена, чтобы скопировать строку подключения. В следующем разделе вы добавите значение строки подключения в переменную среды.

    Снимок экрана, на котором показано, как скопировать строку подключения с портала Azure

Настройка строки подключения хранилища

После копирования строки подключения запишите ее в переменной среды на локальном компьютере, где выполняется приложение. Чтобы задать переменную среды, откройте окно консоли и следуйте инструкциям для используемой операционной системы. Замените <yourconnectionstring> фактической строкой подключения.

setx AZURE_STORAGE_CONNECTION_STRING "<yourconnectionstring>"

После добавления переменной среды в Windows вам необходимо запустить новый экземпляр командного окна.

Перезапуск программ

После добавления переменной среды перезапустите все запущенные программы, которым может понадобиться считать переменную среды. Например, перезапустите среду разработки или редактор, прежде чем продолжить.

Добавление строки подключения в приложение

Добавьте в приложение строку подключения, чтобы оно могло обращаться к учетной записи хранения.

  1. Вернитесь к окну Visual Studio Code.

  2. В методе Main замените код Console.WriteLine("Hello, World"); следующей строкой, которая получает строку подключения из переменной среды.

    string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
    
  3. Добавьте в Main следующий код, который создает объект очереди для последующей передачи в методы отправки и получения данных.

    QueueClient queue = new QueueClient(connectionString, "mystoragequeue");
    
  4. Сохраните файл.

Вставка сообщения в очередь

Создайте новый метод для отправки сообщения в очередь.

  1. Добавьте в класс Program следующий метод InsertMessageAsync.

    Этому методу передается ссылка на очередь. Если очередь не существует, она создается при вызове CreateIfNotExistsAsync. Затем в очередь добавляется newMessage с помощью вызова SendMessageAsync.

    static async Task InsertMessageAsync(QueueClient theQueue, string newMessage)
    {
        if (null != await theQueue.CreateIfNotExistsAsync())
        {
            Console.WriteLine("The queue was created.");
        }
    
        await theQueue.SendMessageAsync(newMessage);
    }
    
  2. Необязательно. По умолчанию максимальное время хранения сообщения составляет 7 дней. Для срока жизни сообщения можно указать любое положительное число. В следующем фрагменте кода добавляется сообщение, для которого срок действия никогда не истекает.

    Чтобы добавить сообщение с неограниченным сроком действия, укажите Timespan.FromSeconds(-1) в вызове функции SendMessageAsync.

    await theQueue.SendMessageAsync(newMessage, default, TimeSpan.FromSeconds(-1), default);
    
  3. Сохраните файл.

Сообщение очереди должно иметь формат, совместимый с XML-запросом в кодировке UTF-8. Размер сообщения может достигать 64 КБ. Если сообщение содержит двоичные данные, примените к нему кодировку Base64.

Вывод сообщений из очереди

Создайте новый метод для получения сообщения из очереди. Очень важно удалять из очереди успешно полученные сообщения, чтобы они не обрабатывались более одного раза.

  1. Добавьте новый метод с именем RetrieveNextMessageAsync в класс Program.

    Этот метод получает сообщение из очереди, вызывая ReceiveMessagesAsync со значением 1 в первом параметре, чтобы получить только следующее сообщение из очереди. Получив сообщение, удалите его из очереди с помощью метода DeleteMessageAsync.

    Когда сообщение отправляется в очередь с помощью пакета SDK до версии 12, оно автоматически кодируется в Base64. Начиная с версии 12 кодировка не применяется. При извлечении сообщения с помощью пакета SDK версии 12 оно не декодируется автоматически. Необходимо явным образом выполнить для содержимого декодирование из Base64.

    static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
    {
        if (await theQueue.ExistsAsync())
        {
            QueueProperties properties = await theQueue.GetPropertiesAsync();
    
            if (properties.ApproximateMessagesCount > 0)
            {
                QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                string theMessage = retrievedMessage[0].Body.ToString();
                await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                return theMessage;
            }
    
            return null;
        }
    
        return null;
    }
    
  2. Сохраните файл.

Удаление пустой очереди

По завершении работы с проектом мы рекомендуем всегда оценивать, нужны ли вам созданные ресурсы. Работающие ресурсы могут означать лишние затраты. Если очередь существует, но пуста, предложите пользователю удалить ее.

  1. Дополните метод RetrieveNextMessageAsync запросом на удаление пустой очереди.

    static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
    {
        if (await theQueue.ExistsAsync())
        {
            QueueProperties properties = await theQueue.GetPropertiesAsync();
    
            if (properties.ApproximateMessagesCount > 0)
            {
                QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                string theMessage = retrievedMessage[0].Body.ToString();
                await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                return theMessage;
            }
            else
            {
                Console.Write("The queue is empty. Attempt to delete it? (Y/N) ");
                string response = Console.ReadLine();
    
                if (response.ToUpper() == "Y")
                {
                    await theQueue.DeleteIfExistsAsync();
                    return "The queue was deleted.";
                }
                else
                {
                    return "The queue was not deleted.";
                }
            }
        }
        else
        {
            return "The queue does not exist. Add a message to the command line to create the queue and store the message.";
        }
    }
    
  2. Сохраните файл.

Проверка аргументов командной строки

Если в приложение переданы аргументы командной строки, мы будем считать их сообщением для добавления в очередь. Объедините эти аргументы в одну строку. Добавьте эту строку в очередь сообщений, вызвав добавленный ранее метод InsertMessageAsync.

Если в командной строке нет аргументов, выполните попытку извлечения. Вызовите метод RetrieveNextMessageAsync, чтобы получить следующее сообщение из очереди.

Перед завершением работы дождитесь ввода пользователя, используя метод Console.ReadLine.

  1. Дополните метод Main проверкой аргументов командной строки и ожиданием действий пользователя.

    static async Task Main(string[] args)
    {
        string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");
    
        QueueClient queue = new QueueClient(connectionString, "mystoragequeue");
    
        if (args.Length > 0)
        {
            string value = String.Join(" ", args);
            await InsertMessageAsync(queue, value);
            Console.WriteLine($"Sent: {value}");
        }
        else
        {
            string value = await RetrieveNextMessageAsync(queue);
            Console.WriteLine($"Received: {value}");
        }
    
        Console.Write("Press Enter...");
        Console.ReadLine();
    }
    
  2. Сохраните файл.

Полный код

Ниже приведен полный код для этого проекта.

using System;
using System.Threading.Tasks;
using Azure.Storage.Queues;
using Azure.Storage.Queues.Models;

namespace QueueApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            string connectionString = Environment.GetEnvironmentVariable("AZURE_STORAGE_CONNECTION_STRING");

            QueueClient queue = new QueueClient(connectionString, "mystoragequeue");

            if (args.Length > 0)
            {
                string value = String.Join(" ", args);
                await InsertMessageAsync(queue, value);
                Console.WriteLine($"Sent: {value}");
            }
            else
            {
                string value = await RetrieveNextMessageAsync(queue);
                Console.WriteLine($"Received: {value}");
            }

            Console.Write("Press Enter...");
            Console.ReadLine();
        }

        static async Task InsertMessageAsync(QueueClient theQueue, string newMessage)
        {
            if (null != await theQueue.CreateIfNotExistsAsync())
            {
                Console.WriteLine("The queue was created.");
            }

            await theQueue.SendMessageAsync(newMessage);
        }

        static async Task<string> RetrieveNextMessageAsync(QueueClient theQueue)
        {
            if (await theQueue.ExistsAsync())
            {
                QueueProperties properties = await theQueue.GetPropertiesAsync();

                if (properties.ApproximateMessagesCount > 0)
                {
                    QueueMessage[] retrievedMessage = await theQueue.ReceiveMessagesAsync(1);
                    string theMessage = retrievedMessage[0].Body.ToString();
                    await theQueue.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
                    return theMessage;
                }
                else
                {
                    Console.Write("The queue is empty. Attempt to delete it? (Y/N) ");
                    string response = Console.ReadLine();

                    if (response.ToUpper() == "Y")
                    {
                        await theQueue.DeleteIfExistsAsync();
                        return "The queue was deleted.";
                    }
                    else
                    {
                        return "The queue was not deleted.";
                    }
                }
            }
            else
            {
                return "The queue does not exist. Add a message to the command line to create the queue and store the message.";
            }
        }
    }
}

Создание и запуск приложения

  1. В командной строке в каталоге проекта выполните следующую команду dotnet, чтобы скомпилировать проект.

    dotnet build
    
  2. Когда сборка проекта успешно завершится, выполните следующую команду для добавления первого сообщения в очередь.

    dotnet run First queue message
    

    Вы должны увидеть такой результат:

    C:\Tutorials\QueueApp>dotnet run First queue message
    The queue was created.
    Sent: First queue message
    Press Enter..._
    
  3. Запустите приложение без аргументов командной строки, чтобы получить и удалить первое сообщение из очереди.

    dotnet run
    
  4. Еще несколько раз выполните приложение, пока не закончатся сообщения в очереди. При следующем запуске вы получите сообщение о том, что очередь пуста, и запрос на ее удаление.

    C:\Tutorials\QueueApp>dotnet run First queue message
    The queue was created.
    Sent: First queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run Second queue message
    Sent: Second queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run Third queue message
    Sent: Third queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: First queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: Second queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    Received: Third queue message
    Press Enter...
    
    C:\Tutorials\QueueApp>dotnet run
    The queue is empty. Attempt to delete it? (Y/N) Y
    Received: The queue was deleted.
    Press Enter...
    
    C:\Tutorials\QueueApp>_
    

Дальнейшие действия

В этом руководстве вы узнали, как выполнять следующие задачи:

  1. Создание очереди
  2. Добавление и удаление сообщений из очереди
  3. Удаление очереди Хранилища очередей Azure

Дополнительные сведения см. в кратких руководствах по Хранилищу очередей Azure.

Примеры кода, использующие устаревшие пакеты SDK для .NET версии 11.x, см. в статье Примеры кода с использованием .NET версии 11.x.