다음을 통해 공유


Java에서 Queue Storage를 사용하는 방법

개요

이 가이드에서는 Azure Queue Storage 서비스를 사용하여 일반적인 시나리오를 코딩하는 방법을 보여 줍니다. 샘플은 Java로 작성되었으며 Java Azure Storage SDK를 사용합니다. 시나리오에는 삽입, 피크, 가져오기, 및 큐 메시지 삭제가 포함됩니다. 에 대한을 생성하고 에 대한 큐를 삭제하는 코드도 포함됩니다. 큐에 대한 자세한 내용은 다음 단계 섹션을 참조하세요.

Queue Storage란?

Azure Queue Storage는 HTTP 또는 HTTPS를 사용하여 인증된 호출을 통해 전 세계 어디에서나 액세스할 수 있는 많은 메시지를 저장하는 서비스입니다. 단일 큐 메시지의 크기는 최대 64KB일 수 있으며 큐에는 스토리지 계정의 총 용량 제한까지 수백만 개의 메시지가 포함될 수 있습니다. Queue Storage는 비동기적으로 처리할 작업의 백로그를 만드는 데 자주 사용됩니다.

큐 시스템 서비스 개념

Azure Queue 서비스에는 다음 구성 요소가 포함됩니다.

Azure Queue Service 구성 요소Azure Queue service componentsAzure Queue service components

  • Storage 계정: Azure Storage에 대한 모든 액세스는 스토리지 계정을 통해 수행됩니다. 스토리지 계정에 대한 자세한 내용은 스토리지 계정 개요를 참조하세요.

  • 큐: 큐에는 메시지 집합이 포함됩니다. 모든 메시지는 대기열에 포함되어야 합니다. 큐 이름은 모두 소문자여야 합니다. 큐의 명명에 대한 자세한 내용은 큐 및 메타데이터 명명을 참조하세요.

  • 메시지: 최대 64KB인 임의 형식의 메시지입니다. 메시지가 큐에 남아 있을 수 있는 최대 시간은 7일입니다. 2017-07-29 이상 버전에서는 최대 수명 시간이 양수일 수 있으며, 메시지가 만료되지 않음을 나타내는 -1도 가능합니다. 이 매개 변수를 생략하면 기본 TTL(Time to Live)은 7일입니다.

  • URL 형식: 큐는 다음 URL 형식인 http://<storage account>.queue.core.windows.net/<queue> 사용하여 주소를 지정할 수 있습니다.

    다음 URL은 다이어그램의 큐를 가리킵니다.

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

Azure Storage 계정 만들기

첫 번째 Azure Storage 계정을 만드는 가장 쉬운 방법은 Azure Portal사용하는 것입니다. 자세한 내용은 스토리지 계정 만들기를 참조하십시오.

Azure PowerShell, Azure CLI또는 .NET용 Azure Storage 리소스 공급자를 사용하여 Azure Storage 계정을 만들 수도.

현재 Azure에서 스토리지 계정을 만들지 않으려는 경우 Azurite 스토리지 에뮬레이터를 사용하여 로컬 환경에서 코드를 실행하고 테스트할 수도 있습니다. 자세한 내용은 로컬 Azure Storage 개발Azurite 에뮬레이터를 사용합니다.

Java 애플리케이션 만들기

먼저 개발 시스템이 Java Azure Queue Storage 클라이언트 라이브러리 v12에 나열된 필수 조건을 충족하는지 확인합니다.

queues-how-to-v12Java 애플리케이션을 만들려면:

  1. 콘솔 창(예: cmd, PowerShell 또는 Bash)에서 Maven을 사용하여 이름이 queues-how-to-v12새 콘솔 앱을 만듭니다. 다음 mvn 명령을 입력하여 "hello world" Java 프로젝트를 만듭니다.

     mvn archetype:generate \
         --define interactiveMode=n \
         --define groupId=com.queues.howto \
         --define artifactId=queues-howto-v12 \
         --define archetypeArtifactId=maven-archetype-quickstart \
         --define archetypeVersion=1.4
    
    mvn archetype:generate `
        --define interactiveMode=n `
        --define groupId=com.queues.howto `
        --define artifactId=queues-howto-v12 `
        --define archetypeArtifactId=maven-archetype-quickstart `
        --define archetypeVersion=1.4
    
  2. 프로젝트를 생성하는 출력은 다음과 같습니다.

    [INFO] Scanning for projects...
    [INFO]
    [INFO] ------------------< org.apache.maven:standalone-pom >-------------------
    [INFO] Building Maven Stub Project (No POM) 1
    [INFO] --------------------------------[ pom ]---------------------------------
    [INFO]
    [INFO] >>> maven-archetype-plugin:3.1.2:generate (default-cli) > generate-sources @ standalone-pom >>>
    [INFO]
    [INFO] <<< maven-archetype-plugin:3.1.2:generate (default-cli) < generate-sources @ standalone-pom <<<
    [INFO]
    [INFO]
    [INFO] --- maven-archetype-plugin:3.1.2:generate (default-cli) @ standalone-pom ---
    [INFO] Generating project in Batch mode
    [INFO] ----------------------------------------------------------------------------
    [INFO] Using following parameters for creating project from Archetype: maven-archetype-quickstart:1.4
    [INFO] ----------------------------------------------------------------------------
    [INFO] Parameter: groupId, Value: com.queues.howto
    [INFO] Parameter: artifactId, Value: queues-howto-v12
    [INFO] Parameter: version, Value: 1.0-SNAPSHOT
    [INFO] Parameter: package, Value: com.queues.howto
    [INFO] Parameter: packageInPathFormat, Value: com/queues/howto
    [INFO] Parameter: version, Value: 1.0-SNAPSHOT
    [INFO] Parameter: package, Value: com.queues.howto
    [INFO] Parameter: groupId, Value: com.queues.howto
    [INFO] Parameter: artifactId, Value: queues-howto-v12
    [INFO] Project created from Archetype in dir: C:\queues\queues-howto-v12
    [INFO] ------------------------------------------------------------------------
    [INFO] BUILD SUCCESS
    [INFO] ------------------------------------------------------------------------
    [INFO] Total time:  6.775 s
    [INFO] Finished at: 2020-08-17T15:27:31-07:00
    [INFO] ------------------------------------------------------------------------
    
  3. 새로 만든 queues-howto-v12 디렉터리로 전환합니다.

    cd queues-howto-v12
    

패키지 설치

텍스트 편집기에서 pom.xml 파일을 엽니다. 종속성 그룹에 다음 종속성 요소를 추가합니다.

<dependency>
  <groupId>com.azure</groupId>
  <artifactId>azure-storage-queue</artifactId>
  <version>12.6.0</version>
</dependency>

Queue Storage에 액세스하도록 애플리케이션 구성

Azure Storage API를 사용하여 큐에 액세스하려는 Java 파일의 맨 위에 다음 import 문을 추가합니다.

// Include the following imports to use queue APIs
import com.azure.core.util.*;
import com.azure.storage.queue.*;
import com.azure.storage.queue.models.*;

Azure Storage 연결 문자열 설정

Azure Storage 클라이언트는 데이터 관리 서비스에 액세스하기 위해 스토리지 연결 문자열을 사용합니다. Azure Portal나열된 스토리지 계정의 이름 및 기본 액세스 키를 가져옵니다. 연결 문자열에서 AccountNameAccountKey 값으로 사용합니다. 이 예제는 정적 필드가 연결 문자열을 포함할 수 있도록 선언하는 방법을 보여 줍니다.

// Define the connection-string with your values
final String connectStr = 
    "DefaultEndpointsProtocol=https;" +
    "AccountName=your_storage_account;" +
    "AccountKey=your_storage_account_key";

다음 샘플에서는 스토리지 연결 문자열을 포함하는 String 개체가 있다고 가정합니다.

큐를 만드는 방법

QueueClient 개체에는 큐와 상호 작용하기 위한 작업이 포함됩니다. 다음 코드는 QueueClient 개체를 만듭니다. QueueClient 개체를 사용하여 사용할 큐를 만듭니다.

public static String createQueue(String connectStr)
{
    try
    {
        // Create a unique name for the queue
        String queueName = "queue-" + java.util.UUID.randomUUID();

        System.out.println("Creating queue: " + queueName);

        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queue = new QueueClientBuilder()
                                .connectionString(connectStr)
                                .queueName(queueName)
                                .buildClient();

        // Create the queue
        queue.create();
        return queue.getQueueName();
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println("Error code: " + e.getErrorCode() + "Message: " + e.getMessage());
        return null;
    }
}

방법: 큐에 메시지 추가

기존 큐에 메시지를 삽입하려면 sendMessage 메서드를 호출합니다. 메시지는 문자열(UTF-8 형식) 또는 바이트 배열일 수 있습니다. 다음은 큐에 문자열 메시지를 보내는 코드입니다.

public static void addQueueMessage
    (String connectStr, String queueName, String messageText)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        System.out.println("Adding message to the queue: " + messageText);

        // Add a message to the queue
        queueClient.sendMessage(messageText);
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

방법: 다음 메시지를 미리 보기

peekMessage를 호출하여 큐에서 메시지를 제거하지 않고 큐의 앞쪽에 있는 메시지를 엿볼 수 있습니다.

public static void peekQueueMessage
    (String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // Peek at the first message
        PeekedMessageItem peekedMessageItem = queueClient.peekMessage();
        System.out.println("Peeked message: " + peekedMessageItem.getMessageText());
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

방법: 큐에 대기된 메시지의 내용 변경

큐에서 메시지의 내용을 직접 수정할 수 있습니다. 메시지가 작업 작업을 나타내는 경우 이 기능을 사용하여 상태를 업데이트할 수 있습니다. 다음 코드는 큐 메시지를 새 콘텐츠로 업데이트하고 표시 시간 제한을 30초 더 연장하도록 설정합니다. 표시 시간 제한을 연장하면 클라이언트가 메시지 작업을 계속하는 데 30초가 더 걸립니다. 재시도 횟수도 유지할 수 있습니다. 메시지가 n번 이상 재시도되는 경우 메시지를 삭제합니다. 이 시나리오는 처리될 때마다 애플리케이션 오류를 트리거하는 메시지로부터 보호합니다.

다음 코드 샘플은 메시지 큐를 검색하고, 검색 문자열과 일치하는 첫 번째 메시지 콘텐츠를 찾고, 메시지 콘텐츠를 수정하고, 종료합니다.

public static void updateQueueMessage
    (String connectStr, String queueName,
    String searchString, String updatedContents)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // The maximum number of messages to retrieve is 32
        final int MAX_MESSAGES = 32;

        // Iterate through the queue messages
        for (QueueMessageItem message : queueClient.receiveMessages(MAX_MESSAGES))
        {
            // Check for a specific string
            if (message.getMessageText().equals(searchString))
            {
                // Update the message to be visible in 30 seconds
                queueClient.updateMessage(message.getMessageId(),
                                          message.getPopReceipt(),
                                          updatedContents,
                                          Duration.ofSeconds(30));
                System.out.println(
                    String.format("Found message: \'%s\' and updated it to \'%s\'",
                                    searchString,
                                    updatedContents)
                                  );
                break;
            }
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

다음 코드 샘플은 큐에 표시되는 첫 번째 메시지만 업데이트합니다.

public static void updateFirstQueueMessage
    (String connectStr, String queueName, String updatedContents)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // Get the first queue message
        QueueMessageItem message = queueClient.receiveMessage();

        // Check for a specific string
        if (null != message)
        {
            // Update the message to be visible in 30 seconds
            UpdateMessageResult result = queueClient.updateMessage(message.getMessageId(),
                                                                   message.getPopReceipt(),
                                                                   updatedContents,
                                                                   Duration.ofSeconds(30));
            System.out.println("Updated the first message with the receipt: " +
                    result.getPopReceipt());
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

큐의 길이 구하기 방법

큐에 있는 메시지의 추정된 개수를 가져올 수 있습니다.

getProperties 메서드는 현재 큐에 있는 메시지 수를 포함하여 여러 값을 반환합니다. 요청 후에 메시지를 추가하거나 제거할 수 있기 때문에 개수는 근사치입니다. getApproximateMessageCount 메서드는 Queue Storage를 호출하지 않고 getProperties호출에 의해 검색된 마지막 값을 반환합니다.

public static void getQueueLength(String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        QueueProperties properties = queueClient.getProperties();
        long messageCount = properties.getApproximateMessagesCount();

        System.out.println(String.format("Queue length: %d", messageCount));
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

방법: 다음 메시지를 큐에서 제거하기

다음 코드는 2단계를 거쳐 큐에서 메시지를 제거합니다. receiveMessage를 호출하면 큐에서 다음 메시지를 가져옵니다. receiveMessage에서 반환된 메시지는 이 큐의 메시지를 읽는 다른 코드에는 표시되지 않습니다. 기본적으로 이 메시지는 30초 동안 보이지 않습니다. 큐에서 메시지 제거를 완료하려면 deleteMessage도 호출해야 합니다. 코드에서 메시지를 처리하지 못하는 경우 이 2단계 프로세스를 통해 동일한 메시지를 받고 다시 시도할 수 있습니다. 코드는 메시지가 처리된 직후에 deleteMessage를 호출합니다.

public static void dequeueMessage(String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // Get the first queue message
        QueueMessageItem message = queueClient.receiveMessage();

        // Check for a specific string
        if (null != message)
        {
            System.out.println("Dequeing message: " + message.getMessageText());

            // Delete the message
            queueClient.deleteMessage(message.getMessageId(), message.getPopReceipt());
        }
        else
        {
            System.out.println("No visible messages in queue");
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

메시지 큐에서 제거하기 위한 추가 옵션

큐에서 메시지 검색을 사용자 지정하는 방법에는 두 가지가 있습니다. 먼저 메시지 일괄 처리를 가져옵니다(최대 32개). 둘째, 더 길거나 더 짧은 투명 시간 제한을 설정하여 코드가 각 메시지를 완전히 처리하는 데 더 많거나 적은 시간을 허용합니다.

다음 코드 예제는 receiveMessages 메서드를 사용하여 한 번 호출에 20개의 메시지를 가져옵니다. 그런 다음에 for 루프를 사용하여 각 메시지를 처리합니다. 또한 각 메시지에 대해 보이지 않으면 시간 제한을 5분(300초)으로 설정합니다. 모든 메시지에 대한 시간 제한이 동시에 시작됩니다. receiveMessages호출 후 5분이 지나면 삭제되지 않은 모든 메시지가 다시 표시됩니다.

public static void dequeueMessages(String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        // The maximum number of messages to retrieve is 20
        final int MAX_MESSAGES = 20;

        // Retrieve 20 messages from the queue with a
        // visibility timeout of 300 seconds (5 minutes)
        for (QueueMessageItem message : queueClient.receiveMessages(MAX_MESSAGES,
                Duration.ofSeconds(300), Duration.ofSeconds(1), new Context("key1", "value1")))
        {
            // Do processing for all messages in less than 5 minutes,
            // deleting each message after processing.
            System.out.println("Dequeing message: " + message.getMessageText());
            queueClient.deleteMessage(message.getMessageId(), message.getPopReceipt());
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

큐 목록 나열 방법

현재 큐 목록을 가져오려면 QueueServiceClient.listQueues() 메서드를 호출하여 QueueItem 개체 컬렉션을 반환합니다.

public static void listQueues(String connectStr)
{
    try
    {
        // Instantiate a QueueServiceClient which will be
        // used to list the queues
        QueueServiceClient queueServiceClient = new QueueServiceClientBuilder()
                                    .connectionString(connectStr)
                                    .buildClient();

        // Loop through the collection of queues.
        for (QueueItem queue : queueServiceClient.listQueues())
        {
            // Output each queue name.
            System.out.println(queue.getName());
        }
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

어떻게 큐를 삭제하는지

큐 및 큐에 포함된 모든 메시지를 삭제하려면 delete 객체에서 QueueClient 메서드를 호출하십시오.

public static void deleteMessageQueue(String connectStr, String queueName)
{
    try
    {
        // Instantiate a QueueClient which will be
        // used to create and manipulate the queue
        QueueClient queueClient = new QueueClientBuilder()
                                    .connectionString(connectStr)
                                    .queueName(queueName)
                                    .buildClient();

        System.out.println("Deleting queue: " + queueClient.getQueueName());

        // Delete the queue
        queueClient.delete();
    }
    catch (QueueStorageException e)
    {
        // Output the exception message and stack trace
        System.out.println(e.getMessage());
        e.printStackTrace();
    }
}

팁 (조언)

Azure Storage 코드 샘플 리포지토리 확인

다운로드하고 실행할 수 있는 엔드투엔드 Azure Storage 코드 샘플을 쉽게 사용하려면 Azure Storage 샘플 목록을 확인하세요.

다음 단계

이제 Queue Storage의 기본 사항을 배웠으므로 다음 링크를 따라 더 복잡한 스토리지 작업에 대해 알아봅니다.

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