Azure Service Bus 큐에서 메시지 보내기 및 받기(Java)

이 빠른 시작에서는 Azure Service Bus 큐에서 메시지를 보내고 받는 Java 앱을 만듭니다.

참고 항목

이 빠른 시작은 Service Bus 큐에 메시지를 보내고 받는 간단한 시나리오에 대한 단계별 지침을 제공합니다. GitHub의 Java용 Azure SDK 리포지토리에서 Azure Service Bus용으로 미리 빌드된 Java 샘플을 찾을 수 있습니다.

Spring 애플리케이션에서 Azure Service Bus 리소스로 작업하는 경우 대안으로 Spring Cloud Azure를 고려하는 것이 좋습니다. Spring Cloud Azure는 Azure 서비스와 원활한 Spring 통합을 제공하는 오픈 소스 프로젝트입니다. Spring Cloud Azure에 대해 자세히 알아보고 Service Bus를 사용하는 예를 보려면 Azure Service Bus를 사용한 Spring Cloud Stream을 참조하세요.

필수 구성 요소

Azure Portal에서 네임스페이스 만들기

Azure에서 Service Bus 메시징 엔터티 사용을 시작하려면 먼저 Azure에서 고유한 이름인 네임스페이스를 만들어야 합니다. 네임스페이스는 애플리케이션 내의 Service Bus 리소스(큐, 토픽 등)에 대한 범위 지정 컨테이너를 제공합니다.

네임스페이스를 만들려면

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

  2. 모든 서비스 페이지이동합니다.

  3. 왼쪽 탐색 모음의 범주 목록에서 통합을 선택하고 Service Bus 위로 마우스를 가리킨 다음 Service Bus 타일에서 단추를 선택합니다+.

    Image showing selection of Create a resource, Integration, and then Service Bus in the menu.

  4. 네임스페이스 만들기 페이지의 기본 사항 태그에서 다음 단계를 수행합니다.

    1. 구독에 대해 네임스페이스를 만들 Azure 구독을 선택합니다.

    2. 리소스 그룹에 대해 네임스페이스가 있는 기존 리소스 그룹을 선택하거나 새로 만듭니다.

    3. 네임스페이스 이름을 입력합니다. 네임스페이스 이름은 다음 명명 규칙을 따라야 합니다.

      • 이름은 Azure에서 고유해야 합니다. 시스템에서 사용 가능한 이름인지 즉시 확인합니다.
      • 이름 길이는 6~50자여야 합니다.
      • 이름에는 문자, 숫자, "-" 하이픈만 포함될 수 있습니다.
      • 이름은 문자로 시작하고 문자 또는 숫자로 끝나야 합니다.
      • 이름은 "-sb" 또는 "-mgmt"로 끝나지 않습니다.
    4. 위치에 대해 네임스페이스가 호스팅되어야하는 지역을 선택합니다.

    5. 가격 책정 계층에 대해 네임스페이스에 대한 가격 책정 계층(기본, 표준 또는 프리미엄)을 선택합니다. 이 빠른 시작의 경우 표준을 선택합니다.

      Important

      토픽 및 구독을 사용하려면 표준 또는 프리미엄을 선택합니다. 토픽/구독은 기본 가격 책정 계층에서 지원되지 않습니다.

      프리미엄 가격 책정 계층을 선택한 경우 메시징 단위 수를 지정합니다. 프리미엄 계층은 CPU 및 메모리 수준에서 리소스 격리를 제공하므로 각 워크로드가 독립적으로 실행됩니다. 이 리소스 컨테이너를 메시징 단위라고 합니다. 프리미엄 네임스페이스에는 하나 이상의 메시징 단위가 있습니다. 각 Service Bus 프리미엄 네임스페이스에 대해 1, 2, 4, 8 또는 16개의 메시징 단위를 선택할 수 있습니다. 자세한 내용은 Service Bus 프리미엄 메시징을 참조하세요.

    6. 페이지 아래쪽에서 검토 + 만들기를 선택합니다.

      Image showing the Create a namespace page

    7. 검토 + 만들기 페이지에서 설정을 검토하고 만들기를 선택합니다.

  5. 리소스 배포에 성공하면 배포 페이지에서 리소스로 이동을 선택합니다.

    Image showing the deployment succeeded page with the Go to resource link.

  6. Service Bus 네임스페이스에 대한 홈페이지가 표시됩니다.

    Image showing the home page of the Service Bus namespace created.

Azure Portal에서 큐 만들기

  1. Service Bus 네임스페이스 페이지의 왼쪽 탐색 메뉴에서 를 선택합니다.

  2. 페이지의 도구 모음에서 + 큐를 선택합니다.

  3. 이름을 입력하고 다른 값은 기본값으로 유지합니다.

  4. 이제 만들기를 선택합니다.

    Image showing creation of a queue in the portal

Azure에 앱 인증

이 빠른 시작에서는 Azure Service Bus에 연결하는 두 가지 방법인 암호 없음연결 문자열을 보여줍니다.

첫 번째 옵션은 Microsoft Entra ID 및 RBAC(역할 기반 액세스 제어)의 보안 주체를 사용하여 Service Bus 네임스페이스에 연결하는 방법을 보여 줍니다. 코드, 구성 파일 또는 Azure Key Vault와 같은 보안 스토리지에 하드 코딩된 연결 문자열이 있는지 걱정할 필요가 없습니다.

두 번째 옵션은 연결 문자열을 사용하여 Service Bus 네임스페이스에 연결하는 방법을 보여줍니다. Azure를 처음 사용하는 경우 연결 문자열 옵션이 더 쉬울 수 있습니다. 실제 애플리케이션 및 프로덕션 환경에서는 암호 없는 옵션을 사용하는 것이 좋습니다. 자세한 내용은 인증 및 권한 부여를 참조하세요. 개요 페이지에서 암호 없는 인증에 대해 자세히 알아볼 수도 있습니다.

Microsoft Entra 사용자에게 역할 할당

로컬에서 개발할 때 Azure Service Bus에 연결하는 사용자 계정에 올바른 권한이 있는지 확인합니다. 메시지를 보내고 받으려면 Azure Service Bus 데이터 소유자 역할이 필요합니다. 자신에게 이 역할을 할당하려면 사용자 액세스 관리자 역할 또는 Microsoft.Authorization/roleAssignments/write 작업을 포함하는 다른 역할이 필요합니다. Azure Portal, Azure CLI 또는 Azure PowerShell을 사용하여 사용자에게 Azure RBAC 역할을 할당할 수 있습니다. 범위 개요 페이지에서 역할 할당에 사용할 수 있는 범위에 대해 자세히 알아봅니다.

다음 예에서는 Azure Service Bus 리소스에 대한 모든 권한을 제공하는 Azure Service Bus Data Owner 역할을 사용자 계정에 할당합니다. 실제 시나리오에서는 최소 권한 원칙에 따라 사용자에게 보다 안전한 프로덕션 환경에 필요한 최소한의 권한만 부여합니다.

Azure Service Bus에 대한 Azure 기본 제공 역할

Azure Service Bus의 경우 Azure Portal 및 Azure 리소스 관리 API를 통한 네임스페이스 및 관련된 모든 리소스의 관리는 이미 Azure RBAC 모델을 사용하여 보호되고 있습니다. Azure는 Service Bus 네임스페이스에 대한 액세스 권한을 부여하기 위해 아래와 같은 Azure 기본 제공 역할을 제공합니다.

  • Azure Service Bus 데이터 소유자: Service Bus 네임스페이스 및 해당 엔터티(큐, 토픽, 구독 및 필터)에 대한 데이터 액세스를 사용하도록 설정합니다. 이 역할의 멤버는 큐 또는 토픽/구독에서 메시지를 보내고 받을 수 있습니다.
  • Azure Service Bus 데이터 보내는 사람: 이 역할을 사용하여 Service Bus 네임스페이스 및 해당 엔터티에 대한 전송 액세스 권한을 부여합니다.
  • Azure Service Bus 데이터 받는 사람: 이 역할을 사용하여 Service Bus 네임스페이스 및 해당 엔터티에 대한 수신 액세스 권한을 부여합니다.

사용자 지정 역할을 만들려면 Service Bus 작업에 필요한 권한을 참조하세요.

Azure Service Bus 소유자 역할에 Microsoft Entra 사용자 추가

Service Bus 네임스페이스 수준에서 Azure Service Bus 데이터 소유자 역할에 Microsoft Entra 사용자 이름을 추가합니다. 사용자 계정의 컨텍스트에서 실행되는 앱이 큐 또는 토픽에 메시지를 보내고 큐 또는 토픽의 구독에서 메시지를 받을 수 있습니다.

Important

대부분의 경우 역할 할당이 Azure에서 전파되는 데 1~2분이 걸립니다. 드문 경우지만 최대 8분이 소요될 수 있습니다. 코드를 처음 실행할 때 인증 오류가 발생하면 잠시 기다렸다가 다시 시도하세요.

  1. Azure Portal에 Service Bus 네임스페이스 페이지가 열려 있지 않은 경우 기본 검색 창이나 왼쪽 탐색 모음을 사용하여 Service Bus 네임스페이스를 찾습니다.

  2. 개요 페이지의 왼쪽 메뉴에서 액세스 제어(IAM)를 선택합니다.

  3. 액세스 제어(IAM) 페이지에서 역할 할당 탭을 선택합니다.

  4. 위쪽 메뉴에서 + 추가를 선택한 다음, 드롭다운 메뉴에서 역할 할당 추가를 선택합니다.

    A screenshot showing how to assign a role.

  5. 검색 상자를 사용하여 결과를 원하는 역할로 필터링합니다. 이 예에서는 Azure Service Bus Data Owner를 검색하고 일치하는 결과를 선택합니다. 다음을 선택합니다.

  6. 다음에 대한 액세스 할당 아래에서 사용자, 그룹 또는 서비스 주체를 선택한 다음, + 멤버 선택을 선택합니다.

  7. 대화 상자에서 Microsoft Entra 사용자 이름(일반적으로 user@domain 이메일 주소)을 검색한 다음, 대화 상자 하단에서 선택을 선택합니다.

  8. 검토 + 할당을 선택하여 최종 페이지로 이동한 다음, 검토 + 할당을 다시 선택하여 프로세스를 완료합니다.

큐에 메시지 보내기

이 섹션에서는 Java 콘솔 프로젝트를 만들고 이전에 만든 큐에 메시지를 보내는 코드를 추가합니다.

Java 콘솔 프로젝트 만들기

Eclipse 또는 원하는 도구를 사용하여 Java 프로젝트를 만듭니다.

Service Bus를 사용하도록 애플리케이션 구성

Azure Core 및 Azure Service Bus 라이브러리에 대한 참조를 추가합니다.

Eclipse를 사용하고 Java 콘솔 애플리케이션을 만든 경우 Java 프로젝트를 Maven으로 변환합니다. 패키지 탐색기 창에서 프로젝트를 마우스 오른쪽 단추로 클릭하고 구성 ->Maven 프로젝트로 변환을 선택합니다. 그런 다음, 다음 예제와 같이 이러한 두 라이브러리에 종속성을 추가합니다.

Azure Service Bus 및 Azure ID 패키지에 종속성을 추가하도록 pom.xml 파일을 업데이트합니다.

    <dependencies>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-messaging-servicebus</artifactId>
            <version>7.13.3</version>
        </dependency>
        <dependency>
            <groupId>com.azure</groupId>
            <artifactId>azure-identity</artifactId>
            <version>1.8.0</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

메시지를 큐에 보내는 코드 추가

  1. Java 파일 토픽에 다음 import 문을 추가합니다.

    import com.azure.messaging.servicebus.*;
    import com.azure.identity.*;
    
    import java.util.concurrent.TimeUnit;
    import java.util.Arrays;
    import java.util.List;
    
  2. 클래스에서 연결 문자열 및 큐 이름을 저장할 변수를 정의합니다.

    static String queueName = "<QUEUE NAME>";
    

    Important

    <QUEUE NAME>을 큐 이름으로 바꿉니다.

  3. 하나의 메시지를 큐에 보내는 sendMessage라는 메서드를 클래스에 추가합니다.

    Important

    NAMESPACENAME를 Service Bus 네임스페이스의 이름으로 바꿉니다.

    static void sendMessage()
    {
        // create a token using the default Azure credential
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .build();
    
        ServiceBusSenderClient senderClient = new ServiceBusClientBuilder()
                .fullyQualifiedNamespace("NAMESPACENAME.servicebus.windows.net")
                .credential(credential)
                .sender()
                .queueName(queueName)
                .buildClient();
    
        // send one message to the queue
        senderClient.sendMessage(new ServiceBusMessage("Hello, World!"));
        System.out.println("Sent a single message to the queue: " + queueName);
    }
    
    
  4. 메시지 목록을 만드는 createMessages라는 메서드를 클래스에 추가합니다. 일반적으로 이러한 메시지는 애플리케이션의 여러 부분에서 가져옵니다. 여기서는 샘플 메시지의 목록을 만듭니다.

    static List<ServiceBusMessage> createMessages()
    {
        // create a list of messages and return it to the caller
        ServiceBusMessage[] messages = {
                new ServiceBusMessage("First message"),
                new ServiceBusMessage("Second message"),
                new ServiceBusMessage("Third message")
        };
        return Arrays.asList(messages);
    }
    
  5. 만든 큐에 메시지를 보내는 sendMessageBatch라는 메서드를 추가합니다. 이 메서드는 큐에 대한 ServiceBusSenderClient를 만들고, createMessages 메서드를 호출하여 메시지 목록을 가져오고, 하나 이상의 일괄 처리를 준비하고, 해당 일괄 처리를 큐에 보냅니다.

    Important

    NAMESPACENAME를 Service Bus 네임스페이스의 이름으로 바꿉니다.

    static void sendMessageBatch()
    {
        // create a token using the default Azure credential
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .build();
    
        ServiceBusSenderClient senderClient = new ServiceBusClientBuilder()
                .fullyQualifiedNamespace("NAMESPACENAME.servicebus.windows.net")
                .credential(credential)
                .sender()
                .queueName(queueName)
                .buildClient();
    
        // Creates an ServiceBusMessageBatch where the ServiceBus.
        ServiceBusMessageBatch messageBatch = senderClient.createMessageBatch();
    
        // create a list of messages
        List<ServiceBusMessage> listOfMessages = createMessages();
    
        // We try to add as many messages as a batch can fit based on the maximum size and send to Service Bus when
        // the batch can hold no more messages. Create a new batch for next set of messages and repeat until all
        // messages are sent.
        for (ServiceBusMessage message : listOfMessages) {
            if (messageBatch.tryAddMessage(message)) {
                continue;
            }
    
            // The batch is full, so we create a new batch and send the batch.
            senderClient.sendMessages(messageBatch);
            System.out.println("Sent a batch of messages to the queue: " + queueName);
    
            // create a new batch
            messageBatch = senderClient.createMessageBatch();
    
            // Add that message that we couldn't before.
            if (!messageBatch.tryAddMessage(message)) {
                System.err.printf("Message is too large for an empty batch. Skipping. Max size: %s.", messageBatch.getMaxSizeInBytes());
            }
        }
    
        if (messageBatch.getCount() > 0) {
            senderClient.sendMessages(messageBatch);
            System.out.println("Sent a batch of messages to the queue: " + queueName);
        }
    
        //close the client
        senderClient.close();
    }
    

큐에서 메시지 받기

이 섹션에서는 큐에서 메시지를 검색하는 코드를 추가합니다.

  1. 큐에서 메시지를 받는 receiveMessages라는 메서드를 추가합니다. 이 메서드는 메시지를 처리하기 위한 처리기 및 오류를 처리하기 위한 다른 처리기를 지정하여 큐에 대한 ServiceBusProcessorClient를 만듭니다. 그런 다음, 프로세서를 시작하고, 몇 초 동안 기다리고, 받은 메시지를 출력한 다음, 프로세서를 중지하고 닫습니다.

    Important

    • NAMESPACENAME를 Service Bus 네임스페이스의 이름으로 바꿉니다.
    • 코드에서 QueueTest::processMessageQueueTest를 클래스 이름으로 바꿉니다.
    // handles received messages
    static void receiveMessages() throws InterruptedException
    {
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .build();
    
        ServiceBusProcessorClient processorClient = new ServiceBusClientBuilder()
                .fullyQualifiedNamespace("NAMESPACENAME.servicebus.windows.net")
                .credential(credential)
                .processor()
                .queueName(queueName)
                .processMessage(context -> processMessage(context))
                .processError(context -> processError(context))
                .buildProcessorClient();
    
        System.out.println("Starting the processor");
        processorClient.start();
    
        TimeUnit.SECONDS.sleep(10);
        System.out.println("Stopping and closing the processor");
        processorClient.close();
    }
    
  2. processMessage 메서드를 추가하여 Service Bus 구독에서 받은 메시지를 처리합니다.

    private static void processMessage(ServiceBusReceivedMessageContext context) {
        ServiceBusReceivedMessage message = context.getMessage();
        System.out.printf("Processing message. Session: %s, Sequence #: %s. Contents: %s%n", message.getMessageId(),
            message.getSequenceNumber(), message.getBody());
    }
    
  3. processError 메서드를 추가하여 오류 메시지를 처리합니다.

    private static void processError(ServiceBusErrorContext context) {
        System.out.printf("Error when receiving messages from namespace: '%s'. Entity: '%s'%n",
            context.getFullyQualifiedNamespace(), context.getEntityPath());
    
        if (!(context.getException() instanceof ServiceBusException)) {
            System.out.printf("Non-ServiceBusException occurred: %s%n", context.getException());
            return;
        }
    
        ServiceBusException exception = (ServiceBusException) context.getException();
        ServiceBusFailureReason reason = exception.getReason();
    
        if (reason == ServiceBusFailureReason.MESSAGING_ENTITY_DISABLED
            || reason == ServiceBusFailureReason.MESSAGING_ENTITY_NOT_FOUND
            || reason == ServiceBusFailureReason.UNAUTHORIZED) {
            System.out.printf("An unrecoverable error occurred. Stopping processing with reason %s: %s%n",
                reason, exception.getMessage());
        } else if (reason == ServiceBusFailureReason.MESSAGE_LOCK_LOST) {
            System.out.printf("Message lock lost for message: %s%n", context.getException());
        } else if (reason == ServiceBusFailureReason.SERVICE_BUSY) {
            try {
                // Choosing an arbitrary amount of time to wait until trying again.
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                System.err.println("Unable to sleep for period of time");
            }
        } else {
            System.out.printf("Error source %s, reason %s, message: %s%n", context.getErrorSource(),
                reason, context.getException());
        }
    }
    
  4. sendMessage, sendMessageBatchreceiveMessages 메서드를 호출하고 InterruptedException을 throw하도록 main 메서드를 업데이트합니다.

    public static void main(String[] args) throws InterruptedException {
        sendMessage();
        sendMessageBatch();
        receiveMessages();
    }
    

앱 실행

  1. Eclipse를 사용하는 경우 프로젝트를 마우스 오른쪽 단추로 클릭하고 내보내기를 선택하고 Java를 확장하고 실행 가능한 JAR 파일을 선택한 후 단계에 따라 실행 가능한 JAR 파일을 만듭니다.

  2. Azure Service Bus 데이터 소유자 역할에 추가된 사용자 계정과 다른 사용자 계정을 사용하여 컴퓨터에 로그인한 경우 다음 단계를 수행합니다. 그렇지 않으면 이 단계를 건너뛰고 다음 단계에서 Jar 파일을 실행합니다.

    1. 컴퓨터에 Azure CLI를 설치합니다.

    2. 다음 CLI 명령을 실행하여 Azure에 로그인합니다. Azure Service Bus 데이터 소유자 역할에 추가한 것과 동일한 사용자 계정을 사용합니다.

      az login
      
  3. 다음 명령을 사용하여 Jar 파일을 실행합니다.

    java -jar <JAR FILE NAME>
    
  4. 콘솔 창에서 다음과 같은 출력이 표시됩니다.

    Sent a single message to the queue: myqueue
    Sent a batch of messages to the queue: myqueue
    Starting the processor
    Processing message. Session: 88d961dd801f449e9c3e0f8a5393a527, Sequence #: 1. Contents: Hello, World!
    Processing message. Session: e90c8d9039ce403bbe1d0ec7038033a0, Sequence #: 2. Contents: First message
    Processing message. Session: 311a216a560c47d184f9831984e6ac1d, Sequence #: 3. Contents: Second message
    Processing message. Session: f9a871be07414baf9505f2c3d466c4ab, Sequence #: 4. Contents: Third message
    Stopping and closing the processor
    

Service Bus 네임스페이스에 대한 Azure Portal의 개요 페이지에서 들어오는 메시지나가는 메시지의 수를 확인할 수 있습니다. 1분 정도 기다린 다음 페이지를 새로 고쳐 최신 값을 확인합니다.

Incoming and outgoing message count

개요 페이지에서 큐를 선택하여 Service Bus 큐 페이지로 이동합니다. 이 페이지에도 들어오는 메시지나가는 메시지의 수가 표시됩니다. 또한 큐의 현재 크기, 최대 크기, 활성 메시지 수 등과 같은 다른 정보도 표시됩니다.

Queue details

다음 단계

다음 설명서와 샘플을 참조하세요.