Share via


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

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

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

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

필수 조건

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

Azure Storage 계정 만들기

먼저, Azure Storage 계정을 만듭니다. 스토리지 계정을 만드는 방법에 대한 단계별 지침은 스토리지 계정 만들기를 참조하세요. 이 단계는 필수 구성 요소에서 무료 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를 호출하기 전에 Azure Portal에서 자격 증명을 가져와야 합니다.

Azure Portal에서 자격 증명 복사

샘플 애플리케이션이 Azure Storage에 대한 요청을 수행하는 경우 권한이 있어야 합니다. 요청에 권한을 부여하려면 스토리지 계정 자격 증명을 연결 문자열로 애플리케이션에 추가합니다. 스토리지 계정 자격 증명을 보려면 다음 단계를 따릅니다.

  1. Azure Portal에 로그인합니다.

  2. 스토리지 계정을 찾습니다.

  3. 스토리지 계정 메뉴 창의 보안 + 네트워킹에서 액세스 키를 선택합니다. 여기에서 계정 액세스 키 및 각 키의 전체 연결 문자열을 볼 수 있습니다.

    Screenshot that shows where the access key settings are in the Azure portal

  4. 액세스 키 창에서 키 표시를 선택합니다.

  5. key1 섹션에서 연결 문자열 값을 찾습니다. 클립보드에 복사 아이콘을 선택하여 연결 문자열을 복사합니다. 다음 단계에서 연결 문자열 값을 환경 변수에 추가합니다.

    Screenshot showing how to copy a connection string from the Azure portal

스토리지 연결 문자열 구성

연결 문자열을 복사한 후 애플리케이션을 실행 중인 로컬 컴퓨터의 새 환경 변수에 씁니다. 환경 변수를 설정하려면 콘솔 창을 열고 사용 중인 운영 체제의 지침을 따릅니다. <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에 추가합니다. 이 개체는 나중에 send 및 receive 메서드에 전달됩니다.

    QueueClient queue = new QueueClient(connectionString, "mystoragequeue");
    
  4. 파일을 저장합니다.

큐에 메시지 삽입

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

  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 메서드를 확장합니다.

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

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

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