Partilhar via


Enviar mensagens para um tópico do Barramento de Serviço do Azure e receber mensagens de assinaturas para o tópico (Java)

Neste início rápido, você escreve código Java usando o pacote azure-messaging-servicebus para enviar mensagens para um tópico do Barramento de Serviço do Azure e, em seguida, receber mensagens de assinaturas desse tópico.

Nota

Este início rápido fornece instruções passo a passo para um cenário simples de enviar um lote de mensagens para um tópico do Service Bus e receber essas mensagens de uma assinatura do tópico. Você pode encontrar exemplos Java pré-criados para o Barramento de Serviço do Azure no repositório do SDK do Azure para Java no GitHub.

Gorjeta

Se você estiver trabalhando com recursos do Barramento de Serviço do Azure em um aplicativo Spring, recomendamos que considere o Spring Cloud Azure como uma alternativa. O Spring Cloud Azure é um projeto de código aberto que fornece integração perfeita do Spring com os serviços do Azure. Para saber mais sobre o Spring Cloud Azure e ver um exemplo usando o Service Bus, consulte Spring Cloud Stream com o Azure Service Bus.

Pré-requisitos

Criar um espaço de nomes no portal do Azure

Para começar a utilizar as entidades de mensagens do Service Bus no Azure, tem de, primeiro, criar um espaço de nomes que seja exclusivo em todo o Azure. Um namespace fornece um contêiner de escopo para recursos do Service Bus (filas, tópicos, etc.) em seu aplicativo.

Para criar um espaço de nomes:

  1. Inicie sessão no portal do Azure.

  2. Navegue até a página Todos os serviços.

  3. Na barra de navegação esquerda, selecione Integração na lista de categorias, passe o mouse sobre o Service Bus e selecione + o botão no bloco do Service Bus.

    Imagem mostrando a seleção de Criar um recurso, Integração e, em seguida, Service Bus no menu.

  4. Na marca Basics da página Criar namespace, siga estas etapas:

    1. Em Assinatura, escolha uma assinatura do Azure na qual criar o namespace.

    2. Para Grupo de recursos, escolha um grupo de recursos existente ou crie um novo.

    3. Insira um nome para o namespace. O nome do namespace deve aderir às seguintes convenções de nomenclatura:

      • O nome deve ser exclusivo no Azure. O sistema verifica imediatamente a disponibilidade do nome.
      • O comprimento do nome é de pelo menos 6 e no máximo 50 caracteres.
      • O nome pode conter apenas letras, números hífenes -.
      • O nome deve começar com uma letra e terminar com uma letra ou número.
      • O nome não termina com -sb ou -mgmt.
    4. Em Local, escolha a região na qual seu namespace deve ser hospedado.

    5. Em Nível de preço, selecione o nível de preço (Básico, Standard ou Premium) para o namespace. Para este início rápido, selecione Padrão.

    6. Se você selecionar a camada Premium , selecione se é possível habilitar a replicação geográfica para o namespace. O recurso de replicação geográfica garante que os metadados e os dados de um namespace sejam replicados continuamente de uma região primária para uma ou mais regiões secundárias.

      Importante

      Se você quiser usar tópicos e assinaturas, escolha Standard ou Premium. Não há suporte para tópicos/assinaturas no nível de preço Básico.

      Se você selecionou o nível de preço Premium, especifique o número de unidades de mensagens. A camada premium fornece isolamento de recursos no nível de CPU e memória para que cada carga de trabalho seja executada isoladamente. Este contentor de recursos é designado por unidade de mensagens. Um namespace premium tem pelo menos uma unidade de mensagens. Você pode selecionar 1, 2, 4, 8 ou 16 unidades de mensagens para cada namespace Premium do Service Bus. Para obter mais informações, consulte Mensagens Premium do Service Bus.

    7. Selecione Rever + criar na parte inferior da página.

      Imagem mostrando a página Criar um namespace

    8. Na página Rever + criar, reveja as definições e selecione Criar.

  5. Quando a implantação do recurso for bem-sucedida, selecione Ir para o recurso na página de implantação.

    Imagem mostrando a página de implantação bem-sucedida com o link Ir para recurso.

  6. Você vê a home page do namespace do barramento de serviço.

    Imagem mostrando a home page do namespace do Service Bus criado.

Criar um tópico com o portal do Azure

  1. Na página Namespace do Service Bus, expanda Entidades no menu de navegação à esquerda e selecione Tópicos no menu à esquerda.

  2. Selecione + Tópico na barra de ferramentas.

  3. Insira um nome para o tópico. Deixe as outras opções com os valores predefinidos.

  4. Selecione Criar.

    Imagem mostrando a página Criar tópico.

Criar uma subscrição para o tópico

  1. Selecione o tópico que você criou na seção anterior.

    Imagem mostrando a seleção de tópicos da lista de tópicos.

  2. Na página Tópico do Service Bus, selecione + Assinatura na barra de ferramentas.

    Imagem mostrando o botão Adicionar assinatura.

  3. Na página Criar subscrição, siga estes passos:

    1. Digite S1 para o nome da assinatura.

    2. Digite 3 para Contagem máxima de entregas.

    3. Em seguida, selecione Criar para criar a assinatura.

      Imagem mostrando a página Criar assinatura.

Autenticar o aplicativo no Azure

Este início rápido mostra duas maneiras de se conectar ao Barramento de Serviço do Azure: sem senha e cadeia de conexão.

A primeira opção mostra como usar sua entidade de segurança no Microsoft Entra ID e RBAC (controle de acesso baseado em função) para se conectar a um namespace do Service Bus. Você não precisa se preocupar em ter uma cadeia de conexão codificada em seu código ou em um arquivo de configuração ou em um armazenamento seguro como o Azure Key Vault.

A segunda opção mostra como usar uma cadeia de conexão para se conectar a um namespace do Service Bus. Se você for novo no Azure, poderá achar a opção de cadeia de conexão mais fácil de seguir. Recomendamos o uso da opção sem senha em aplicativos e ambientes de produção do mundo real. Para obter mais informações, consulte Autenticação e autorização. Você também pode ler mais sobre autenticação sem senha na página de visão geral.

Atribuir funções ao usuário do Microsoft Entra

Ao desenvolver localmente, verifique se a conta de usuário que se conecta ao Barramento de Serviço do Azure tem as permissões corretas. Você precisará da função Proprietário de Dados do Barramento de Serviço do Azure para enviar e receber mensagens. Para atribuir essa função a si mesmo, você precisará da função de Administrador de Acesso de Usuário ou de outra função que inclua a Microsoft.Authorization/roleAssignments/write ação. Você pode atribuir funções do RBAC do Azure a um usuário usando o portal do Azure, a CLI do Azure ou o Azure PowerShell. Saiba mais sobre os escopos disponíveis para atribuições de função na página de visão geral do escopo.

O exemplo a seguir atribui a Azure Service Bus Data Owner função à sua conta de usuário, que fornece acesso total aos recursos do Barramento de Serviço do Azure. Em um cenário real, siga o Princípio do Menor Privilégio para dar aos usuários apenas as permissões mínimas necessárias para um ambiente de produção mais seguro.

Funções internas do Azure para o Barramento de Serviço do Azure

Para o Barramento de Serviço do Azure, o gerenciamento de namespaces e todos os recursos relacionados por meio do portal do Azure e da API de gerenciamento de recursos do Azure já está protegido usando o modelo RBAC do Azure. O Azure fornece as seguintes funções internas do Azure para autorizar o acesso a um namespace do Service Bus:

Se você quiser criar uma função personalizada, consulte Direitos necessários para operações do Service Bus.

Adicionar usuário do Microsoft Entra à função de Proprietário do Barramento de Serviço do Azure

Adicione seu nome de usuário do Microsoft Entra à função Proprietário de Dados do Barramento de Serviço do Azure no nível do namespace do Barramento de Serviço. Ele permitirá que um aplicativo em execução no contexto da sua conta de usuário envie mensagens para uma fila ou um tópico e receba mensagens de uma fila ou da assinatura de um tópico.

Importante

Na maioria dos casos, levará um ou dois minutos para que a atribuição de função se propague no Azure. Em casos raros, pode demorar até oito minutos. Se você receber erros de autenticação quando executar o código pela primeira vez, aguarde alguns momentos e tente novamente.

  1. Se você não tiver a página Namespace do Service Bus aberta no portal do Azure, localize seu namespace do Service Bus usando a barra de pesquisa principal ou a navegação à esquerda.

  2. Na página de visão geral, selecione Controle de acesso (IAM) no menu à esquerda.

  3. Na página Controle de acesso (IAM), selecione a guia Atribuições de função.

  4. Selecione + Adicionar no menu superior e, em seguida, Adicionar atribuição de função no menu suspenso resultante.

    Uma captura de tela mostrando como atribuir uma função.

  5. Use a caixa de pesquisa para filtrar os resultados para a função desejada. Para este exemplo, procure Azure Service Bus Data Owner e selecione o resultado correspondente. Em seguida, escolha Avançar.

  6. Em Atribuir acesso a, selecione Utilizador, grupo ou entidade de serviço e, em seguida, selecione + Selecionar membros.

  7. Na caixa de diálogo, procure seu nome de usuário do Microsoft Entra (geralmente seu endereço de e-mail user@domain ) e escolha Selecionar na parte inferior da caixa de diálogo.

  8. Selecione Rever + atribuir para ir para a página final e, em seguida , Rever + atribuir novamente para concluir o processo.

Enviar mensagens para um tópico

Nesta seção, você cria um projeto de console Java e adiciona código para enviar mensagens ao tópico criado.

Criar um projeto de console Java

Crie um projeto Java usando o Eclipse ou uma ferramenta de sua escolha.

Configurar seu aplicativo para usar o Service Bus

Adicione referências às bibliotecas do Azure Core e do Azure Service Bus.

Se você estiver usando o Eclipse e tiver criado um aplicativo de console Java, converta seu projeto Java em um Maven: clique com o botão direito do mouse no projeto na janela Package Explorer , selecione Configure ->Convert to Maven project. Em seguida, adicione dependências a essas duas bibliotecas, conforme mostrado no exemplo a seguir.

Atualize o pom.xml arquivo para adicionar dependências aos pacotes do Barramento de Serviço do Azure e do Azure Identity.

    <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>

Adicionar código para enviar mensagens ao tópico

  1. Adicione as seguintes import instruções no tópico do arquivo Java.

    import com.azure.messaging.servicebus.*;
    import com.azure.identity.*;
    
    import java.util.concurrent.TimeUnit;
    import java.util.Arrays;
    import java.util.List;
    
  2. Na classe, defina variáveis para manter a cadeia de conexão (não necessária para o cenário sem senha), nome do tópico e nome da assinatura.

    static String topicName = "<TOPIC NAME>";
    static String subName = "<SUBSCRIPTION NAME>";
    

    Importante

    Substitua <TOPIC NAME> pelo nome do tópico e <SUBSCRIPTION NAME> pelo nome da assinatura do tópico.

  3. Adicione um método nomeado sendMessage na classe para enviar uma mensagem para o tópico.

    Importante

    Substitua NAMESPACENAME pelo nome do espaço de nomes do 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()
                .topicName(topicName)
                .buildClient();
    
        // send one message to the topic
        senderClient.sendMessage(new ServiceBusMessage("Hello, World!"));
        System.out.println("Sent a single message to the topic: " + topicName);
    }
    
    
  4. Adicione um método nomeado createMessages na classe para criar uma lista de mensagens. Normalmente, você recebe essas mensagens de diferentes partes do seu aplicativo. Aqui, criamos uma lista de exemplos de mensagens.

    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. Adicione um método chamado sendMessageBatch método para enviar mensagens para o tópico que você criou. Esse método cria um ServiceBusSenderClient para o tópico, invoca o createMessages método para obter a lista de mensagens, prepara um ou mais lotes e envia os lotes para o tópico.

    Importante

    Substitua NAMESPACENAME pelo nome do espaço de nomes do 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()
                .topicName(topicName)
                .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 topic: " + topicName);
    
            // 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 topic: " + topicName);
        }
    
        //close the client
        senderClient.close();
    }
    

Receber mensagens de uma subscrição

Nesta seção, você adiciona código para recuperar mensagens de uma assinatura para o tópico.

  1. Adicione um método chamado receiveMessages para receber mensagens da assinatura. Esse método cria um ServiceBusProcessorClient para a assinatura, especificando um manipulador para processar mensagens e outro para lidar com erros. Em seguida, ele inicia o processador, aguarda por alguns segundos, imprime as mensagens recebidas e, em seguida, para e fecha o processador.

    Importante

    • Substitua NAMESPACENAME pelo nome do espaço de nomes do Service Bus.
    • Substitua ServiceBusTopicTest ServiceBusTopicTest::processMessage no código pelo nome da sua classe.
    // handles received messages
    static void receiveMessages() throws InterruptedException
    {
        DefaultAzureCredential credential = new DefaultAzureCredentialBuilder()
                .build();
    
        // Create an instance of the processor through the ServiceBusClientBuilder
        ServiceBusProcessorClient processorClient = new ServiceBusClientBuilder()
            .fullyQualifiedNamespace("NAMESPACENAME.servicebus.windows.net")
            .credential(credential)
            .processor()
            .topicName(topicName)
            .subscriptionName(subName)
            .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. Adicione o processMessage método para processar uma mensagem recebida da assinatura do 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. Adicione o processError método para manipular mensagens de erro.

    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. Atualize o main método para invocar sendMessage, sendMessageBatche receiveMessages métodos e lançar InterruptedException.

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

Executar a aplicação

Execute o programa para ver a saída semelhante à seguinte saída:

  1. Se você estiver usando o Eclipse, clique com o botão direito do mouse no projeto, selecione Exportar, expanda Java, selecione Arquivo JAR executável e siga as etapas para criar um arquivo JAR executável.

  2. Se você estiver conectado à máquina usando uma conta de usuário diferente da conta de usuário adicionada à função de Proprietário de Dados do Barramento de Serviço do Azure, siga estas etapas. Caso contrário, ignore esta etapa e passe a executar o arquivo Jar na próxima etapa.

    1. Instale a CLI do Azure em sua máquina.

    2. Execute o seguinte comando da CLI para entrar no Azure. Use a mesma conta de usuário que você adicionou à função de Proprietário de Dados do Barramento de Serviço do Azure.

      az login
      
  3. Execute o arquivo Jar usando o seguinte comando.

    java -jar <JAR FILE NAME>
    
  4. Você verá a seguinte saída na janela do console.

    Sent a single message to the topic: mytopic
    Sent a batch of messages to the topic: mytopic
    Starting the processor
    Processing message. Session: e0102f5fbaf646988a2f4b65f7d32385, Sequence #: 1. Contents: Hello, World!
    Processing message. Session: 3e991e232ca248f2bc332caa8034bed9, Sequence #: 2. Contents: First message
    Processing message. Session: 56d3a9ea7df446f8a2944ee72cca4ea0, Sequence #: 3. Contents: Second message
    Processing message. Session: 7bd3bd3e966a40ebbc9b29b082da14bb, Sequence #: 4. Contents: Third message
    

Na página Visão geral do namespace do Service Bus no portal do Azure, você pode ver a contagem de mensagens de entrada e saída. Aguarde cerca de um minuto e, em seguida, atualize a página para ver os valores mais recentes.

Contagem de mensagens recebidas e enviadas

Alterne para a guia Tópicos no painel central inferior e selecione o tópico para ver a página Tópico do Service Bus do seu tópico. Nesta página, você verá quatro mensagens de entrada e quatro de saída no gráfico Mensagens .

Mensagens recebidas e enviadas

Se você comentar a receiveMessages main chamada no método e executar o aplicativo novamente, na página Tópico do Service Bus, verá 8 mensagens de entrada (4 novas), mas quatro mensagens de saída.

Página temática atualizada

Nesta página, se selecionar uma subscrição, acede à página Subscrição do Service Bus. Você pode ver a contagem de mensagens ativas, a contagem de mensagens mortas e muito mais nesta página. Neste exemplo, há quatro mensagens ativas que o destinatário ainda não recebeu.

Contagem de mensagens ativas

Próximos passos

Consulte a seguinte documentação e exemplos: