Todos os produtos
Search
Central de documentação

ApsaraMQ for RocketMQ:Envie e receba mensagens com o SDK para Java

Última atualização: Oct 09, 2026

Após criar recursos do ApsaraMQ for RocketMQ, como um tópico e um grupo de consumidores, você pode integrar a mensageria à sua aplicação Java. Este guia mostra como adicionar a dependência do SDK para Java 5.x, conectar-se à sua instância, enviar mensagens normais e consumi-las com um consumidor push ou um consumidor simples.

Antes de começar

Certifique-se de ter:

Adicione a dependência do SDK

  1. Crie um projeto Java na sua IDE.

  2. Adicione a seguinte dependência ao pom.xml:

        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-client-java</artifactId>
            <version>5.0.7</version>
        </dependency>

**FAQ: E se eu receber o erro ClassNotFoundException: com.google.protobuf.GeneratedMessageV3 após adicionar a dependência rocketmq-client-java?**

Esse erro geralmente ocorre devido a um conflito de dependências, em que uma dependência mais antiga no seu projeto, como o rocketmq-spring-boot-starter, interfere ao carregar as classes do Protobuf.

Para resolver esse problema:

  • Certifique-se de que o seu projeto inclua a dependência protobuf-java correta ou isole SDKs de versões diferentes em módulos separados para evitar o conflito.

  • Caso não seja possível dividir os SDKs em módulos separados, adicione explicitamente as dependências rocketmq-proto e protobuf-java.

O SDK rocketmq-client-java usado pelo consumidor simples já inclui uma versão shaded do Protobuf (org.apache.rocketmq.shaded.com.google.protobuf). Na maioria dos casos, não é necessário adicionar com.google.protobuf:protobuf-java separadamente.

Reúna os parâmetros de conexão

Colete os seguintes valores no console do ApsaraMQ for RocketMQ antes de escrever qualquer código:

Parâmetro

Exemplo

Onde encontrar

endpoints

rmq-cn-xxx.{regionId}.rmq.aliyuncs.com:8080

Página Instance Details > aba Endpoints. Use o endpoint de VPC ao acessar a instância a partir de uma instância do Elastic Compute Service (ECS) na mesma VPC, ou o endpoint público para acesso pela Internet. Consulte Obter o endpoint de uma instância.

topic

normal_test

O tópico criado para enviar e receber mensagens. Crie-o previamente. Veja Criar um tópico.

consumerGroup

GID_test

O grupo de consumidores criado. Crie-o previamente. Confira Criar um grupo de consumidores.

InstanceId

rmq-cn-xxx

O ID da sua instância do ApsaraMQ for RocketMQ. Necessário apenas para instâncias serverless acessadas pela Internet.

Nome de usuário da instância

1XVg0hzgKm******

Página Access Control > aba Intelligent Authentication. Veja Obter o nome de usuário e a senha de uma instância.

Senha da instância

ijSt8rEc45******

Mesmo local do nome de usuário.

Quando as credenciais são necessárias

A necessidade de fornecer nome de usuário, senha e namespace depende do seu método de acesso:

Método de acesso

Nome de usuário e senha

Namespace (ID da instância)

VPC (instância padrão)

Não é necessário. O broker obtém as credenciais automaticamente a partir das informações da VPC.

Não é necessário.

VPC (instância serverless, isento de autenticação ativado)

Não é necessário.

Não é necessário.

VPC (instância serverless, isento de autenticação desativado)

É necessário.

Não é necessário.

Internet (instância padrão)

É necessário. Ative primeiro o acesso à Internet na instância.

Não é necessário.

Internet (instância serverless)

É necessário.

É necessário. Defina via .setNamespace("InstanceId").

Envie mensagens

Crie um arquivo ProducerExample.java no seu projeto e execute-o:

import org.apache.rocketmq.client.apis.*;
import org.apache.rocketmq.client.apis.message.Message;
import org.apache.rocketmq.client.apis.producer.Producer;
import org.apache.rocketmq.client.apis.producer.SendReceipt;

public class ProducerExample {
    public static void main(String[] args) throws ClientException {
        // Instance endpoint. Use the VPC endpoint when accessing from an ECS instance in the same VPC; use the public endpoint for Internet access.
        String endpoints = "<your-endpoint>";
        // Topic (must be pre-created in the console)
        String topic = "<your-topic>";

        ClientServiceProvider provider = ClientServiceProvider.loadService();
        ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder()
                .setEndpoints(endpoints)
                // Uncomment for serverless instances accessed over the Internet:
                // .setNamespace("<your-instance-id>")
                // Uncomment for Internet access or serverless VPC without authentication-free:
                // .setCredentialProvider(new StaticSessionCredentialsProvider("<instance-username>", "<instance-password>"))
                .build();

        Producer producer = provider.newProducerBuilder()
                .setTopics(topic)
                .setClientConfiguration(clientConfiguration)
                .build();

        Message message = provider.newMessageBuilder()
                .setTopic(topic)
                .setKeys("messageKey")
                .setTag("messageTag")
                .setBody("messageBody".getBytes())
                .build();
        try {
            SendReceipt sendReceipt = producer.send(message);
            System.out.println(sendReceipt.getMessageId());
        } catch (ClientException e) {
            e.printStackTrace();
        }
    }
}

Substitua os placeholders pelos seus valores:

Placeholder

Descrição

<your-endpoint>

Endpoint da instância, por exemplo rmq-cn-xxx.cn-hangzhou.rmq.aliyuncs.com:8080

<your-topic>

Nome do tópico, por exemplo normal_test

<your-instance-id>

ID da instância (apenas para acesso serverless pela Internet)

<instance-username>

Nome de usuário da instância (acesso pela Internet ou VPC serverless sem autenticação)

<instance-password>

Senha da instância (acesso pela Internet ou VPC serverless sem autenticação)

Nota

O método .setTopics() durante a inicialização do produtor valida as configurações do tópico antecipadamente. Isso é opcional para mensagens normais (validadas dinamicamente no momento do envio), mas obrigatório para mensagens transacionais, a fim de evitar falhas na API de consulta.

Importante

Se falhar o envio de uma mensagem, ela não é gravada no servidor, logo, não é possível consultá-la pelo ID da mensagem no console posteriormente. No código da sua aplicação, capture a exceção (por exemplo, em SendCallback.onException), registre o conteúdo completo da mensagem no log e tente reenviá-la com base na sua lógica de negócios.

Receba mensagens

O ApsaraMQ for RocketMQ oferece dois tipos de consumidores:

Consumidor push

Consumidor simples

Como funciona

O SDK entrega as mensagens a um callback (listener de mensagens).

A aplicação puxa as mensagens e confirma (ack) explicitamente cada uma.

Concorrência

Gerenciada pelo SDK.

Gerenciada pela aplicação.

Flexibilidade

Menor. O SDK encapsula o fluxo de consumo.

Maior. Operações atômicas permitem criar fluxos de trabalho personalizados.

Ideal para

A maioria dos casos de uso em que é necessário processar mensagens recebidas.

Cenários que exigem controle refinado sobre a busca, o processamento ou a confirmação.

Comece com um consumidor push, a menos que seja necessário um controle personalizado sobre o fluxo de consumo.

Nota

Ao usar o rocketmq-spring-boot-starter ou o rocketmq-v5-client-spring-boot-starter para integrar o SDK ao Spring Boot, fique atento às seguintes limitações e diferenças de configuração:

  • A anotação @RocketMQMessageListener no rocketmq-spring-boot-starter suporta apenas o consumidor push. Caso precise de um consumidor simples, inicialize-o manualmente no código, pois a anotação não oferece esse suporte.

  • No rocketmq-v5-client-spring-boot-starter, o consumidor simples e as alterações dinâmicas em sua duração de invisibilidade atualmente também requerem inicialização manual no código. Esses elementos não são injetados automaticamente por meio de anotações.

  • No arquivo de configuração do starter v5, use o parâmetro endpoints em vez do parâmetro name-server usado anteriormente.

  • O parâmetro de namespace difere de acordo com o starter: com o rocketmq-v5-client-spring-boot-starter, configure namespace; com o rocketmq-spring-boot-starter, configure namespaceV2. Caso o arquivo de configuração YAML não suporte esse parâmetro, defina-o no código.

Consumidor push

Crie um arquivo PushConsumerExample.java e execute-o:

import org.apache.rocketmq.client.apis.*;
import org.apache.rocketmq.client.apis.consumer.ConsumeResult;
import org.apache.rocketmq.client.apis.consumer.FilterExpression;
import org.apache.rocketmq.client.apis.consumer.FilterExpressionType;
import org.apache.rocketmq.client.apis.consumer.PushConsumer;
import org.apache.rocketmq.shaded.org.slf4j.Logger;
import org.apache.rocketmq.shaded.org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Collections;

public class PushConsumerExample {
    private static final Logger LOGGER = LoggerFactory.getLogger(PushConsumerExample.class);

    private PushConsumerExample() {
    }

    public static void main(String[] args) throws ClientException, IOException, InterruptedException {
        String endpoints = "<your-endpoint>";
        String topic = "<your-topic>";
        String consumerGroup = "<your-consumer-group>";

        final ClientServiceProvider provider = ClientServiceProvider.loadService();
        ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder()
                .setEndpoints(endpoints)
                // Uncomment for serverless instances accessed over the Internet:
                // .setNamespace("<your-instance-id>")
                // Uncomment for Internet access or serverless VPC without authentication-free:
                // .setCredentialProvider(new StaticSessionCredentialsProvider("<instance-username>", "<instance-password>"))
                .build();

        // Subscribe to all messages in the topic (tag = "*")
        String tag = "*";
        FilterExpression filterExpression = new FilterExpression(tag, FilterExpressionType.TAG);

        PushConsumer pushConsumer = provider.newPushConsumerBuilder()
                .setClientConfiguration(clientConfiguration)
                .setConsumerGroup(consumerGroup)
                .setSubscriptionExpressions(Collections.singletonMap(topic, filterExpression))
                .setMessageListener(messageView -> {
                    System.out.println("Consume Message: " + messageView);
                    return ConsumeResult.SUCCESS;
                })
                .build();

        // Keep the consumer running
        Thread.sleep(Long.MAX_VALUE);

        // To shut down the consumer gracefully, call:
        // pushConsumer.close();
    }
}
Nota

O consumidor push no SDK gRPC do ApsaraMQ for RocketMQ 5.x usa uma fila interna de buffer local. Mesmo com o consumo em thread única, o SDK faz a pré-busca de mensagens para esse buffer. Se a lógica de negócio demorar muito para processar cada mensagem, essa pré-busca pode causar tempos limite de espera locais e usar recursos desnecessariamente.

Para lógicas de negócio de longa duração, use um consumidor simples (modo pull). O consumidor simples permite controlar a quantidade exata de mensagens puxadas por vez. Além disso, puxe o próximo lote apenas após processar e confirmar o lote atual. Defina InvisibleDuration (o período durante o qual uma mensagem recebida permanece invisível para outros consumidores, de 10 segundos a 12 horas) para controlar o tempo limite de confirmação e estendê-lo dinamicamente, se necessário.

Consumidor simples

Crie um arquivo SimpleConsumerExample.java e execute-o:

import org.apache.rocketmq.client.apis.*;
import org.apache.rocketmq.client.apis.consumer.FilterExpression;
import org.apache.rocketmq.client.apis.consumer.FilterExpressionType;
import org.apache.rocketmq.client.apis.consumer.SimpleConsumer;
import org.apache.rocketmq.client.apis.message.MessageId;
import org.apache.rocketmq.client.apis.message.MessageView;
import org.apache.rocketmq.shaded.org.slf4j.Logger;
import org.apache.rocketmq.shaded.org.slf4j.LoggerFactory;

import java.io.IOException;
import java.time.Duration;
import java.util.Collections;
import java.util.List;

public class SimpleConsumerExample {
    private static final Logger LOGGER = LoggerFactory.getLogger(SimpleConsumerExample.class);

    private SimpleConsumerExample() {
    }

    public static void main(String[] args) throws ClientException, IOException {
        String endpoints = "<your-endpoint>";
        String topic = "<your-topic>";
        String consumerGroup = "<your-consumer-group>";

        final ClientServiceProvider provider = ClientServiceProvider.loadService();
        ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder()
                .setEndpoints(endpoints)
                // Uncomment for serverless instances accessed over the Internet:
                // .setNamespace("<your-instance-id>")
                // Uncomment for Internet access or serverless VPC without authentication-free:
                // .setCredentialProvider(new StaticSessionCredentialsProvider("<instance-username>", "<instance-password>"))
                .build();

        // Long polling timeout
        Duration awaitDuration = Duration.ofSeconds(10);
        // Subscribe to all messages in the topic (tag = "*")
        String tag = "*";
        FilterExpression filterExpression = new FilterExpression(tag, FilterExpressionType.TAG);

        SimpleConsumer consumer = provider.newSimpleConsumerBuilder()
                .setClientConfiguration(clientConfiguration)
                .setConsumerGroup(consumerGroup)
                .setAwaitDuration(awaitDuration)
                .setSubscriptionExpressions(Collections.singletonMap(topic, filterExpression))
                .build();

        // Maximum messages per pull
        int maxMessageNum = 16;
        // Messages stay invisible to other consumers for this duration after being received
        Duration invisibleDuration = Duration.ofSeconds(10);

        // Poll for messages in a loop. For real-time consumption, use multiple threads.
        while (true) {
            final List<MessageView> messages = consumer.receive(maxMessageNum, invisibleDuration);
            messages.forEach(messageView -> {
                System.out.println("Received message: " + messageView);
            });
            for (MessageView message : messages) {
                final MessageId messageId = message.getMessageId();
                try {
                    // ACK each message to commit the consumption result to the broker
                    consumer.ack(message);
                    System.out.println("Message is acknowledged successfully, messageId= " + messageId);
                } catch (Throwable t) {
                    t.printStackTrace();
                }
            }
        }
        // To shut down the consumer gracefully, call:
        // consumer.close();
    }
}

Verifique a entrega de mensagens

Verifique o status de entrega no console do ApsaraMQ for RocketMQ:

  1. Acesse o console do ApsaraMQ for RocketMQ.

  2. Na página Instances, clique no nome da instância.

  3. No painel de navegação à esquerda, clique em Message Tracing.

Versões do SDK necessárias para acesso serverless pela Internet

O acesso a uma instância serverless do ApsaraMQ for RocketMQ pela Internet requer uma versão mínima do SDK. Substitua InstanceId nos exemplos pelo ID real da instância.

SDK para Java 5.x (rocketmq-client-java)

Versão mínima: 5.0.6

Defina o namespace em ClientConfiguration:

ClientConfiguration clientConfiguration = ClientConfiguration.newBuilder()
    .setEndpoints(endpoints)
    .setNamespace("InstanceId")
    .setCredentialProvider(sessionCredentialsProvider)
    .build();

SDK para Java 5.x (rocketmq-client)

Versão mínima: 5.2.0

Defina o namespace no produtor e no consumidor, separadamente:

// Producer
producer.setNamespaceV2("InstanceId");

// Consumer
consumer.setNamespaceV2("InstanceId");

SDK de cliente TCP para Java 1.x

Versão mínima: 1.9.0.Final

Defina o namespace por meio das propriedades:

properties.setProperty(PropertyKeyConst.Namespace, "InstanceId");

FAQ: E se ocorrer o erro "The instance version does not support setting user properties" ao enviar uma mensagem?

Esse erro geralmente ocorre devido a uma versão muito antiga do SDK. Para resolvê-lo, atualize o SDK para a versão 1.9.1.Final ou superior e tente novamente.

Próximos passos