Rozpoczynanie pracy z usługą Azure Queue Storage przy użyciu platformy .NET

Omówienie

Usługa Azure Queue Storage umożliwia przesyłanie komunikatów w chmurze między składnikami aplikacji. Podczas projektowania aplikacji na skalę składniki aplikacji są często oddzielone, aby można je było skalować niezależnie. Usługa Queue Storage dostarcza asynchroniczną obsługę komunikatów między składnikami aplikacji, niezależnie od tego, czy działają w chmurze, na komputerze, na serwerze lokalnym, czy na urządzeniu przenośnym. Kolejki Storage obsługują również zarządzanie zadaniami asynchronicznymi i tworzenie przepływów pracy procesów.

Informacje o tym samouczku

W tym samouczku pokazano, jak napisać kod platformy .NET dla niektórych typowych scenariuszy przy użyciu usługi Azure Queue Storage. Omówione scenariusze obejmują tworzenie i usuwanie kolejek oraz dodawanie, odczytywanie i usuwanie komunikatów kolejek.

Szacowany czas trwania: 45 minut

Wymagania wstępne

Co to jest magazyn kolejek?

Azure Queue Storage to usługa do przechowywania dużej liczby komunikatów, do której można uzyskać dostęp z dowolnego miejsca na świecie za pośrednictwem uwierzytelnionego połączenia za pomocą protokołu HTTP lub HTTPS. Pojedynczy komunikat z kolejki nie może przekraczać 64 KB, a kolejka może zawierać miliony komunikatów — maksymalnie liczbę nieprzekraczającą całkowitego limitu pojemności konta magazynu. Magazyn kolejek jest często używany do tworzenia zaległości prac do przetwarzania asynchronicznego.

Koncepcje usługa kolejki

Usługa kolejki platformy Azure zawiera następujące składniki:

Składniki usługi Azure usługa kolejki

  • Konto magazynu: cały dostęp do usługi Azure Storage odbywa się przez konto magazynu. Aby uzyskać więcej informacji na temat kont magazynu, zobacz Omówienie konta magazynu.

  • Kolejka: kolejka zawiera zestaw komunikatów. Wszystkie komunikaty muszą być w kolejce. Pamiętaj, że nazwa kolejki może zawierać tylko małe litery. Informacje dotyczące nazewnictwa kolejek można znaleźć w temacie Naming Queues and Metadata (Nazewnictwo kolejek i metadanych).

  • Komunikat: komunikat w dowolnym formacie, o maksymalnym rozmiarze 64 KB. Maksymalny czas pozostawania komunikatu w kolejce wynosi 7 dni. W wersji 2017-07-29 lub nowszej maksymalny czas wygaśnięcia może być dowolną liczbą dodatnią lub-1 oznacza, że komunikat nie wygasa. Jeśli ten parametr zostanie pominięty, domyślny czas wygaśnięcia wynosi siedem dni.

  • Format adresu URL: Kolejki są adresowane przy użyciu następującego formatu adresu URL: http:// <storage account> . Queue.Core.Windows.NET/<queue>

    Następujący adres URL dotyczy kolejki w schemacie:

    http://myaccount.queue.core.windows.net/incoming-orders

Tworzenie konta usługi Azure Storage

Najprościej jest utworzyć pierwsze konto usługi Azure Storage przy użyciu witryny Azure Portal. Więcej informacji można znaleźć w temacie Tworzenie konta magazynu.

Można również utworzyć konto usługi Azure Storage przy użyciu programu Azure PowerShell, interfejsu wiersza polecenia Azure lub dostawcy zasobów usługi Azure Storage dla platformy .NET.

Jeśli wolisz nie tworzyć konta magazynu na platformie Azure, możesz również użyć emulatora magazynu azurite do uruchamiania i testowania kodu w środowisku lokalnym. Aby uzyskać więcej informacji, zobacz Używanie emulatora azurite na potrzeby tworzenia lokalnych magazynów platformy Azure.

Konfigurowanie środowiska projektowego

Następnie skonfiguruj środowisko projektowe w programie Visual Studio, aby przygotować się do wypróbowania przykładów kodu zawartych w tym przewodniku.

Utwórz projekt aplikacji konsolowej dla systemu Windows

W programie Visual Studio utwórz nową aplikację konsoli dla systemu Windows. Poniższe kroki pokazują, jak utworzyć aplikację konsoli w programie Visual Studio 2019. Procedura jest podobna w innych wersjach programu Visual Studio.

  1. Wybierz pozycję Nowy > > Project
  2. Wybierz pozycję Windows >
  3. Wybierz pozycję Aplikacja konsolowa (.NET Framework)
  4. Wybierz pozycję Dalej
  5. W Project nazwy aplikacji wprowadź nazwę aplikacji
  6. Wybierz pozycję Utwórz

Wszystkie przykłady kodu w tym samouczku można dodać do metody Main() w pliku Program.cs aplikacji konsolowej.

Bibliotek klienckich usługi Azure Storage można używać w aplikacjach .NET dowolnego typu, w tym w usłudze w chmurze lub aplikacji internetowej platformy Azure oraz aplikacjach klasycznych i mobilnych. W tym przewodniku dla uproszczenia przedstawiono aplikację konsolową.

Użycie pakietu NuGet w celu zainstalowania wymaganych pakietów

Aby ukończyć ten samouczek, należy odwołać się do następujących czterech pakietów w projekcie:

Możesz użyć NuGet, aby uzyskać te pakiety. Wykonaj następujące kroki:

  1. Kliknij prawym przyciskiem myszy projekt w Eksplorator rozwiązań, a następnie wybierz pozycję Zarządzaj NuGet pakietów.
  2. Wybierz pozycję Przeglądaj
  3. Wyszukaj w trybie online pozycję , a następnie wybierz pozycję Zainstaluj, aby zainstalować bibliotekę Azure.Storage.Queues klienta Storage Azure i jej zależności. Spowoduje to również zainstalowanie platformy Azure. Storage. Biblioteki Common i Azure.Core, które są zależnościami biblioteki kolejek.
  4. Wyszukaj w trybie System.Configuration.ConfigurationManager online i wybierz pozycję Zainstaluj, aby zainstalować Menedżer konfiguracji.

Określanie środowiska docelowego

W przypadku uruchamiania przykładów w tym przewodniku istnieją dwie opcje środowiska:

  • Można uruchomić kod dla konta usługi Azure Storage w chmurze.
  • Kod można uruchomić w emulatorze magazynu Azurite. Azurite to środowisko lokalne, które emuluje konto usługi Azure Storage w chmurze. Azurite to bezpłatna opcja testowania i debugowania kodu podczas opracowywania aplikacji. Emulator używa dobrze znanego konta i klucza. Aby uzyskać więcej informacji, zobacz Use the Azurite emulator for local Azure Storage development and testing (Tworzenie i testowanie za pomocą emulatora Azurite na Storage Azure).

Uwaga

Na obiekt docelowy można wybrać emulator magazynu, aby uniknąć ponoszenia kosztów związanych z usługą Azure Storage. Jeśli jednak zdecydujesz się na docelowe konto usługi Azure Storage w chmurze, koszty wykonania tego samouczka będą niewielkie.

Uzyskiwanie parametrów połączenia magazynu

Biblioteki klienckie usługi Azure Storage dla platformy .NET obsługują używanie parametrów połączenia magazynu do konfigurowania punktów końcowych i poświadczeń w celu uzyskania dostępu do usług magazynu. Aby uzyskać więcej informacji, zobacz Zarządzanie kluczami dostępu do konta magazynu.

Kopiowanie poświadczeń z witryny Azure Portal

Przykładowy kod musi autoryzować dostęp do konta magazynu. Na potrzeby autoryzacji podajesz aplikacji swoje poświadczenia konta magazynu w postaci parametrów połączenia. Aby wyświetlić swoje poświadczenia konta magazynu:

  1. Przejdź do Azure Portal.

  2. Odszukaj konto magazynu.

  3. W sekcji Ustawienia omówienia kont magazynu wybierz pozycję Klucze dostępu. Zostaną wyświetlone klucze dostępu do Twojego konta, a także pełne parametry połączenia dla każdego klucza.

  4. Znajdź wartość Parametry połączenia w obszarze key1 i kliknij przycisk Kopiuj, aby skopiować parametry połączenia. W następnym kroku dodasz wartość parametrów połączenia do zmiennej środowiskowej.

    Zrzut ekranu pokazujący sposób kopiowania parametrów połączenia z witryny Azure Portal

Aby uzyskać więcej informacji dotyczących parametrów połączenia, zobacz Konfigurowanie parametrów połączenia z usługą Azure Storage.

Uwaga

Klucz konta magazynu jest podobny do hasła głównego konta magazynu. Zawsze chroń klucz konta magazynu. Nie udostępniaj go innym użytkownikom, nie koduj go trwale ani nie zapisuj w zwykłym pliku tekstowym, do którego mają dostęp inne osoby. Wygeneruj ponownie klucz za pośrednictwem witryny Azure Portal, jeśli uważasz, że jego zabezpieczenia mogły zostać naruszone.

Najlepiej przechowywać parametry połączenia magazynu w pliku konfiguracji. Aby skonfigurować parametry połączenia, otwórz plik app.config z Eksploratora rozwiązań w programie Visual Studio. Dodaj zawartość elementu <appSettings> pokazanego tutaj. Zastąp connection-string wartość wartością skopiowaną z konta magazynu w portalu:

<configuration>
    <startup>
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
    </startup>
    <appSettings>
        <add key="StorageConnectionString" value="connection-string" />
    </appSettings>
</configuration>

Na przykład ustawienie konfiguracji może wyglądać mniej więcej tak:

<add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=storagesample;AccountKey=GMuzNHjlB3S9itqZJHHCnRkrokLkcSyW7yK9BRbGp0ENePunLPwBgpxV1Z/pVo9zpem/2xSHXkMqTHHLcx8XRA==EndpointSuffix=core.windows.net" />

Aby użyć docelowego emulatora magazynu Azurite, możesz użyć skrótu, który mapuje na dobrze znaną nazwę konta i klucz. W takim przypadku ustawienie parametrów połączenia wygląda następująco:

<add key="StorageConnectionString" value="UseDevelopmentStorage=true" />

Dodawanie dyrektyw using

Dodaj następujące dyrektywy using na początku pliku Program.cs:

using System; // Namespace for Console output
using System.Configuration; // Namespace for ConfigurationManager
using System.Threading.Tasks; // Namespace for Task
using Azure.Identity;
using Azure.Storage.Queues; // Namespace for Queue storage types
using Azure.Storage.Queues.Models; // Namespace for PeekedMessage

Tworzenie klienta Storage kolejki

Klasa QueueClient umożliwia pobieranie kolejek przechowywanych w kolejce Storage. Oto jeden ze sposobów tworzenia klienta usługi:

//-------------------------------------------------
// Create the queue service client
//-------------------------------------------------
public void CreateQueueClient(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to create and manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);
}

Teraz możesz napisać kod, który odczytuje dane z usługi Queue Storage i zapisuje Storage.

Tworzenie kolejki

W tym przykładzie pokazano, jak utworzyć kolejkę:

//-------------------------------------------------
// Create a message queue
//-------------------------------------------------
public bool CreateQueue(string queueName)
{
    try
    {
        // Get the connection string from app settings
        string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

        // Instantiate a QueueClient which will be used to create and manipulate the queue
        QueueClient queueClient = new QueueClient(connectionString, queueName);

        // Create the queue
        queueClient.CreateIfNotExists();

        if (queueClient.Exists())
        {
            Console.WriteLine($"Queue created: '{queueClient.Name}'");
            return true;
        }
        else
        {
            Console.WriteLine($"Make sure the Azurite storage emulator running and try again.");
            return false;
        }
    }
    catch (Exception ex)
    {
        Console.WriteLine($"Exception: {ex.Message}\n\n");
        Console.WriteLine($"Make sure the Azurite storage emulator running and try again.");
        return false;
    }
}

Wstawianie komunikatu do kolejki

Aby wstawić komunikat do istniejącej kolejki, wywołaj SendMessage metodę . Komunikat może być ciągiem (w formacie UTF-8) lub tablicą bajtów. Poniższy kod tworzy kolejkę (jeśli nie istnieje) i wstawia komunikat:

//-------------------------------------------------
// Insert a message into a queue
//-------------------------------------------------
public void InsertMessage(string queueName, string message)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to create and manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    // Create the queue if it doesn't already exist
    queueClient.CreateIfNotExists();

    if (queueClient.Exists())
    {
        // Send a message to the queue
        queueClient.SendMessage(message);
    }

    Console.WriteLine($"Inserted: {message}");
}

Podgląd kolejnego komunikatu

Możesz podeglądać komunikaty w kolejce bez usuwania ich z kolejki, wywołując PeekMessages metodę . Jeśli nie przekażemy wartości parametru, wartością domyślną jest podejrzanie maxMessages w jednym komunikacie.

//-------------------------------------------------
// Peek at a message in the queue
//-------------------------------------------------
public void PeekMessage(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    { 
        // Peek at the next message
        PeekedMessage[] peekedMessage = queueClient.PeekMessages();

        // Display the message
        Console.WriteLine($"Peeked message: '{peekedMessage[0].Body}'");
    }
}

Zmiana zawartości komunikatu w kolejce

Możesz zmienić zawartość komunikatu w kolejce. Jeśli komunikat reprezentuje zadanie robocze, możesz użyć tej funkcji, aby zaktualizować stan zadania. Poniższy kod aktualizuje komunikat kolejki o nową zawartość i ustawia rozszerzenie limitu czasu widoczności o kolejne 60 sekund. Operacja ta zapisuje stan pracy powiązanej z komunikatem i daje klientowi kolejną minutę na kontynuowanie pracy nad komunikatem. Tej techniki można użyć do śledzenia wieloetapowych przepływów pracy w komunikatach kolejek bez konieczności rozpoczynania od początku, jeśli krok przetwarzania zakończy się niepowodzeniem z powodu awarii sprzętu lub oprogramowania. Zazwyczaj stosuje się również liczbę ponownych prób. Jeśli komunikat zostanie ponowiony więcej niż n razy, zostanie usunięty. Jest to zabezpieczenie przed komunikatami, które wyzwalają błąd aplikacji zawsze, gdy są przetwarzane.

//-------------------------------------------------
// Update an existing message in the queue
//-------------------------------------------------
public void UpdateMessage(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        // Get the message from the queue
        QueueMessage[] message = queueClient.ReceiveMessages();

        // Update the message contents
        queueClient.UpdateMessage(message[0].MessageId, 
                message[0].PopReceipt, 
                "Updated contents",
                TimeSpan.FromSeconds(60.0)  // Make it invisible for another 60 seconds
            );
    }
}

Dequeue the next message (Dequeue the next message)

Wykonuj komunikat z kolejki w dwóch krokach. Po wywołaniu ReceiveMessages wywołania w kolejce zostanie wyświetlony następny komunikat. Komunikat zwrócony z usługi staje ReceiveMessages się niewidoczny dla każdego innego kodu, który odczytuje komunikaty z tej kolejki. Domyślnie komunikat pozostanie niewidoczny przez 30 sekund. Aby zakończyć usuwanie komunikatu z kolejki, musisz również wywołać DeleteMessage . Ten dwuetapowy proces usuwania komunikatów gwarantuje, że jeśli kod nie będzie w stanie przetworzyć komunikatu z powodu awarii sprzętu lub oprogramowania, inne wystąpienie kodu będzie w stanie uzyskać ten sam komunikat i ponowić próbę. Kod wywołuje DeleteMessage kod bezpośrednio po przetworzeniu komunikatu.

//-------------------------------------------------
// Process and remove a message from the queue
//-------------------------------------------------
public void DequeueMessage(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        // Get the next message
        QueueMessage[] retrievedMessage = queueClient.ReceiveMessages();

        // Process (i.e. print) the message in less than 30 seconds
        Console.WriteLine($"Dequeued message: '{retrievedMessage[0].Body}'");

        // Delete the message
        queueClient.DeleteMessage(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
    }
}

Używanie wzorca Async-Await z wspólnymi interfejsami API usługi Queue Storage

W tym przykładzie pokazano, jak używać wzorca Async-Await z wspólnymi interfejsami API usługi Queue Storage. Przykład wywołuje asynchroniczną wersję każdej z podanych metod, co wskazuje Async sufiks każdej metody. W przypadku korzystania z metody asynchronicznej wzorzec Async-Await wstrzymuje wykonywanie lokalne do momentu zakończenia wywołania. Takie zachowanie umożliwia wykonywanie innych zadań przez bieżący wątek, co pomaga unikać wąskich gardeł zmniejszających wydajność i poprawia ogólną szybkość reakcji aplikacji. Aby uzyskać więcej informacji na temat używania wzorca Async-Await na platformie .NET, zobacz Async i Await (C# and Visual Basic)

//-------------------------------------------------
// Perform queue operations asynchronously
//-------------------------------------------------
public async Task QueueAsync(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    // Create the queue if it doesn't already exist
    await queueClient.CreateIfNotExistsAsync();

    if (await queueClient.ExistsAsync())
    {
        Console.WriteLine($"Queue '{queueClient.Name}' created");
    }
    else
    {
        Console.WriteLine($"Queue '{queueClient.Name}' exists");
    }

    // Async enqueue the message
    await queueClient.SendMessageAsync("Hello, World");
    Console.WriteLine($"Message added");

    // Async receive the message
    QueueMessage[] retrievedMessage = await queueClient.ReceiveMessagesAsync();
    Console.WriteLine($"Retrieved message with content '{retrievedMessage[0].Body}'");

    // Async delete the message
    await queueClient.DeleteMessageAsync(retrievedMessage[0].MessageId, retrievedMessage[0].PopReceipt);
    Console.WriteLine($"Deleted message: '{retrievedMessage[0].Body}'");

    // Async delete the queue
    await queueClient.DeleteAsync();
    Console.WriteLine($"Deleted queue: '{queueClient.Name}'");
}

Używanie dodatkowych opcji do dekodowania komunikatów

Istnieją dwa sposoby dostosowania pobierania komunikatów z kolejki. Po pierwsze można uzyskać komunikaty zbiorczo (do 32). Po drugie można ustawić dłuższy lub krótszy limit czasu niewidoczności, dzięki czemu kod będzie mieć więcej lub mniej czasu na pełne przetworzenie każdego komunikatu.

W poniższym przykładzie kodu użyto ReceiveMessages metody , aby uzyskać 20 komunikatów w jednym wywołaniu. Następnie przetwarza każdy komunikat przy użyciu foreach pętli. Ustawia również limitu czasu niewidoczności na pięć minut dla każdego komunikatu. Należy pamiętać, że pięć minut rozpoczyna się dla wszystkich komunikatów w tym samym czasie, więc po pięciu minutach od wywołania do , wszystkie komunikaty, które nie zostały usunięte, staną się ponownie ReceiveMessages widoczne.

//-----------------------------------------------------
// Process and remove multiple messages from the queue
//-----------------------------------------------------
public void DequeueMessages(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        // Receive and process 20 messages
        QueueMessage[] receivedMessages = queueClient.ReceiveMessages(20, TimeSpan.FromMinutes(5));

        foreach (QueueMessage message in receivedMessages)
        {
            // Process (i.e. print) the messages in less than 5 minutes
            Console.WriteLine($"De-queued message: '{message.Body}'");

            // Delete the message
            queueClient.DeleteMessage(message.MessageId, message.PopReceipt);
        }
    }
}

Pobieranie długości kolejki

Możesz uzyskać szacunkową liczbę komunikatów w kolejce. Metoda GetProperties zwraca właściwości kolejki, w tym liczbę komunikatów. Właściwość ApproximateMessagesCount zawiera przybliżoną liczbę komunikatów w kolejce. Ta liczba nie jest mniejsza niż rzeczywista liczba komunikatów w kolejce, ale może być wyższa.

//-----------------------------------------------------
// Get the approximate number of messages in the queue
//-----------------------------------------------------
public void GetQueueLength(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        QueueProperties properties = queueClient.GetProperties();

        // Retrieve the cached approximate message count.
        int cachedMessagesCount = properties.ApproximateMessagesCount;

        // Display number of messages.
        Console.WriteLine($"Number of messages in queue: {cachedMessagesCount}");
    }
}

Usuwanie kolejki

Aby usunąć kolejkę i wszystkie zawarte w niej komunikaty, wywołaj Delete metodę w obiekcie kolejki.

//-------------------------------------------------
// Delete the queue
//-------------------------------------------------
public void DeleteQueue(string queueName)
{
    // Get the connection string from app settings
    string connectionString = ConfigurationManager.AppSettings["StorageConnectionString"];

    // Instantiate a QueueClient which will be used to manipulate the queue
    QueueClient queueClient = new QueueClient(connectionString, queueName);

    if (queueClient.Exists())
    {
        // Delete the queue
        queueClient.Delete();
    }

    Console.WriteLine($"Queue deleted: '{queueClient.Name}'");
}

Następne kroki

Teraz, gdy masz już podstawowe informacje na temat usługi Queue Storage, skorzystaj z poniższych linków, aby dowiedzieć się więcej o bardziej złożonych zadaniach magazynu.