다음을 통해 공유


자습서: .NET에서 Azure Queue Storage 큐 작업

Azure Queue Storage는 분산된 애플리케이션의 구성 요소 간에 통신을 가능하게 해주는 클라우드 기반 큐를 구현합니다. 각 큐는 발신자 구성 요소에서 추가하고 수신자 구성 요소에서 처리할 수 있는 메시지 목록을 유지합니다. 큐를 사용하면 수요에 따라 애플리케이션을 즉시 확장할 수 있습니다. 이 문서에서는 Azure Queue Storage 큐를 사용하기 위한 기본 단계를 보여줍니다.

이 자습서에서는 다음을 하는 방법을 알아볼 수 있습니다.

  • Azure Storage 계정 만들기
  • 앱 만들기
  • Azure 클라이언트 라이브러리 추가
  • 비동기 코드에 대한 지원 추가
  • 큐 만들기
  • 큐에 메시지 삽입
  • 큐에서 메시지 제거
  • 빈 큐 삭제
  • 명령줄 인수 확인
  • 앱 빌드 및 실행

필수 조건

  • 플랫폼 간 Visual Studio Code 편집기의 무료 복사본을 가져옵니다.
  • .NET Core SDK 버전 3.1 이상을 다운로드하여 설치합니다.
  • 현재 Azure 구독이 없는 경우 시작하기 전에 체험 계정을 만듭니다.

Azure Storage 계정 만들기

  1. 먼저, Azure Storage 계정을 만듭니다.

    스토리지 계정을 만드는 방법에 대한 단계별 지침은 스토리지 계정 만들기를 참조하세요. 이 단계는 필수 구성 요소에서 무료 Azure 계정을 만든 후에 수행하는 별도의 단계입니다.

  2. 사용자 계정에 스토리지 계정, 부모 리소스 그룹 또는 구독으로 범위가 지정된 스토리지 큐 데이터 기여자 역할이 할당되었는지 확인합니다. Azure에 대한 인증을 참조하세요.

앱 만들기

QueueApp이라는 .NET Core 응용 프로그램을 만듭니다. 간략한 설명을 위해, 이 앱에서는 큐를 통해 메시지를 보내고 받는 작업을 모두 처리하겠습니다.

  1. cmd, PowerShell 또는 Azure CLI 같은 콘솔 창에서 dotnet new 명령을 사용하여 QueueApp이라는 새 콘솔 앱을 만듭니다. 이 명령은 Program.cs라는 단일 소스 파일을 사용하여 간단한 "hello world" C# 프로젝트를 만듭니다.

    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. dotnet add package 명령을 사용하여 Azure Storage 클라이언트 라이브러리를 프로젝트에 추가합니다.

    콘솔 창의 프로젝트 폴더에서 다음 명령을 실행합니다.

    dotnet add package Azure.Storage.Queues
    

using 문 추가

  1. 프로젝트 디렉터리의 명령줄에 code .를 입력하여 현재 디렉터리에서 Visual Studio Code를 엽니다. 명령줄 창을 계속 열어 둡니다. 이후에 몇 가지 명령을 더 실행해야 합니다. 빌드 및 디버그에 필요한 C# 자산을 추가하라는 메시지가 표시되면 단추를 클릭합니다.

  2. Program.cs 원본 파일을 열고 using System; 문 바로 뒤에 다음 네임스페이스를 추가합니다. 이 앱은 이 네임스페이스의 형식을 사용하여 Azure Storage에 연결하고 큐를 사용합니다.

    using System.Threading.Tasks;
    using Azure.Storage.Queues;
    using Azure.Storage.Queues.Models;
    
  3. Program.cs 파일을 저장합니다.

비동기 코드에 대한 지원 추가

앱에서 클라우드 리소스를 사용하므로 코드가 비동기적으로 실행됩니다.

  1. 비동기 방식으로 실행되도록 Main 메서드를 업데이트합니다. voidasync Task 반환 값으로 대체합니다.

    static async Task Main(string[] args)
    
  2. Program.cs 파일을 저장합니다.

큐 만들기

Azure API를 호출하기 전에 역할을 할당한 것과 동일한 Microsoft Entra 계정으로 인증되었는지 확인해야 합니다. 인증되면 스토리지 계정의 QueueClient 큐 데이터에 액세스하는 데 사용하여 DefaultAzureCredential 개체를 만들고 권한을 부여할 수 있습니다. DefaultAzureCredential 는 로그인한 계정을 자동으로 검색하고 사용합니다. 로그인한 다음 개체를 만드는 QueueClient 방법을 알아보려면 액세스 권한 부여 및 클라이언트 개체 만들기를 참조 하세요.

큐에 메시지 삽입

큐에 메시지를 보내는 새 메서드를 만듭니다.

  1. Program 클래스에 다음 InsertMessageAsync 메서드를 추가합니다.

    이 메서드는 큐 참조에 전달됩니다. 새 큐가 아직 없는 경우 CreateIfNotExistsAsync를 호출하여 새로 만들어집니다. 그런 다음, SendMessageAsync를 호출하여 큐에 newMessage를 추가합니다.

    static async Task InsertMessageAsync(QueueClient theQueue, string newMessage)
    {
        if (null != await theQueue.CreateIfNotExistsAsync())
        {
            Console.WriteLine("The queue was created.");
        }
    
        await theQueue.SendMessageAsync(newMessage);
    }
    
  2. 선택 사항: 기본적으로 메시지의 TTL(Time-To-Live)은 7일로 설정됩니다. 메시지 TTL(Time-To-Live)에 임의 양수를 지정할 수 있습니다. 다음 코드 조각에서는 만료되지 않는 메시지를 추가합니다.

    만기되지 않는 메시지를 추가하려면 SendMessageAsync 호출에 Timespan.FromSeconds(-1)를 사용합니다.

    await theQueue.SendMessageAsync(newMessage, default, TimeSpan.FromSeconds(-1), default);
    
  3. 파일을 저장합니다.

큐 메시지는 UTF-8 인코딩을 사용하여 XML 요청과 호환되는 형식이어야 합니다. 메시지의 크기는 최대 64KB일 수 있습니다. 메시지에 이진 데이터가 포함되어 있으면 메시지를 Base64로 인코딩합니다.

큐에서 메시지 제거

큐에서 메시지를 검색하는 새 메서드를 만듭니다. 메시지가 성공적으로 수신되면 메시지가 여러 번 처리되지 않도록 큐에서 삭제해야 합니다.

  1. Program 클래스에 새로운 RetrieveNextMessageAsync 메서드를 추가합니다.

    이 메서드는 ReceiveMessagesAsync를 호출하여 큐에서 메시지를 받고, 첫 번째 매개 변수에 1을 전달하여 큐에 있는 다음 메시지만 검색합니다. 메시지를 받은 후 DeleteMessageAsync를 호출하여 큐에서 메시지를 삭제합니다.

    v12 이전 버전의 SDK를 사용하여 큐에 메시지를 보내는 경우 해당 메시지는 자동으로 Base64로 인코딩됩니다. v12부터 해당 기능이 제거되었습니다. v12 SDK를 사용하여 메시지를 검색할 때 자동으로 Base64로 디코딩되지 않습니다. 콘텐츠를 직접 명시적으로 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 메서드를 확장합니다. 아래 코드 조각에서 자리 표시자를 스토리지 계정 이름으로 바꿔 {storageAccountName} 야 합니다.

    static async Task Main(string[] args)
    {
       QueueClient queue = new QueueClient(
          new Uri($"https://{storageAccountName}.queue.core.windows.net/mystoragequeue"),
          new DefaultAzureCredential());
    
       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;
using Azure.Identity;

namespace QueueApp
{
    class Program
    {
        static async Task Main(string[] args)
        {
            QueueClient queue = new QueueClient(
               new Uri($"https://{storageAccountName}.queue.core.windows.net/mystoragequeue"),
               new DefaultAzureCredential());

            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 Queue Storage 큐 삭제

자세한 내용은 Azure Queue Storage 빠른 시작을 확인하세요.

사용되지 않는 .NET 버전 11.x SDK를 사용하는 관련 코드 샘플은 .NET 버전 11.x를 사용하는 코드 샘플을 참조하세요.