Todos os produtos
Search
Central de documentação

ApsaraMQ for RocketMQ:Send and subscribe to normal messages with TCP client SDKs

Última atualização: Oct 14, 2026

O ApsaraMQ for RocketMQ oferece SDKs de cliente TCP comerciais para Java, C/C++ e .NET. Este guia orienta você na criação de um producer para enviar mensagens normais, na verificação da entrega e no início de um consumer para assinar essas mensagens.

Nota

Cada tipo de mensagem — normal, agendada, atrasada, ordenada e transacional — exige um tópico dedicado. Não reutilize um tópico de mensagens normais para outros tipos de mensagem.

Antes de começar

Certifique-se de ter:

Etapa 1: Configurar o sdk de cliente tcp

Os SDKs comerciais oferecem mais recursos e maior estabilidade que os SDKs open source. Use os SDKs open source apenas ao migrar de um cluster Apache RocketMQ sem alterações de código.

Escolha a linguagem e siga as instruções de configuração:

Linguagem

Notas de versão

Configuração do ambiente

Código de exemplo

Java

Release notes

Environment preparation

Sample code

C/C++

Release notes

Environment preparation

Sample code

.NET

Release notes

Environment preparation

Sample code

Etapa 2: Enviar mensagens normais

Crie um producer e envie mensagens normais com o código de exemplo a seguir.

Substitua os placeholders pelos valores reais:

Placeholder

Descrição

Onde encontrar

<YOUR_ACCESS_KEY>

AccessKey ID para autenticação

Console do RAM

<YOUR_SECRET_KEY>

AccessKey secret para autenticação

Console do RAM

<YOUR_TOPIC>

Tópico criado para mensagens normais

Console do ApsaraMQ for RocketMQ

<YOUR_GROUP_ID>

Group ID criado no console

Console do ApsaraMQ for RocketMQ

<YOUR_TCP_ENDPOINT>

Endpoint tcp da sua instância

Seção TCP Endpoint na página Instance Details

Java

Nota

No ambiente de Internet de uma instância RocketMQ V4, o uso de um sdk baseado em gRPC, como o ons-client 2.0.x, pode causar erros de verificação de recursos. Recomendamos o uso do ons-client 1.9.1.Final, baseado no protocolo Remoting e compatível com JDK 17. Esta versão oferece a melhor compatibilidade com o ambiente de Internet das instâncias V4.

O exemplo em Java envia uma mensagem de forma assíncrona e retorna o resultado por meio de um callback.

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.OnExceptionContext;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.SendCallback;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;

import java.util.Properties;

public class ProducerTest {
    public static void main(String[] args) {
        Properties properties = new Properties();
        // AccessKey ID for authentication.
        properties.put(PropertyKeyConst.AccessKey, "<YOUR_ACCESS_KEY>");
        // AccessKey secret for authentication.
        properties.put(PropertyKeyConst.SecretKey, "<YOUR_SECRET_KEY>");
        // Timeout for sending a message, in milliseconds.
        properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
        // TCP endpoint of your instance.
        properties.put(PropertyKeyConst.NAMESRV_ADDR, "<YOUR_TCP_ENDPOINT>");

        Producer producer = ONSFactory.createProducer(properties);
        // Call start() once before sending messages.
        producer.start();

        Message msg = new Message(
                // Topic for the message.
                "<YOUR_TOPIC>",
                // Message tag for filtering on the broker.
                "TagA",
                // Message body in binary format.
                // Producer and consumer must agree on serialization and deserialization.
                "Hello MQ".getBytes());

        // Message key: a business-specific identifier, ideally globally unique.
        // Useful for querying or resending messages in the console if delivery fails.
        // Messages can be sent without a key.
        msg.setKey("ORDERID_100");

        // Send the message asynchronously. The result returns through the callback.
        producer.sendAsync(msg, new SendCallback() {
            @Override
            public void onSuccess(final SendResult sendResult) {
                System.out.println("send message success. topic=" +
                    sendResult.getTopic() + ", msgId=" + sendResult.getMessageId());
            }

            @Override
            public void onException(OnExceptionContext context) {
                // Handle the failure: retry or persist the message.
                System.out.println("send message failed. topic=" +
                    context.getTopic() + ", msgId=" + context.getMessageId());
            }
        });

        // The msgId is available before the callback returns.
        System.out.println("send message async. topic=" +
            msg.getTopic() + ", msgId=" + msg.getMsgID());

        // Shut down the producer before exiting. (Optional for Java)
        producer.shutdown();
    }
}

Saída esperada:

send message async. topic=<YOUR_TOPIC>, msgId=...
send message success. topic=<YOUR_TOPIC>, msgId=...

.NET

O exemplo em .NET envia mensagens de forma síncrona em um loop.

using System;
using ons;

public class ProducerExampleForEx
{
    public ProducerExampleForEx()
    {
    }

    static void Main(string[] args) {
        ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
        // AccessKey ID for authentication.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.AccessKey, "<YOUR_ACCESS_KEY>");
        // AccessKey secret for authentication.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.SecretKey, "<YOUR_SECRET_KEY>");
        // Group ID created in the ApsaraMQ for RocketMQ console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.ProducerId, "<YOUR_GROUP_ID>");
        // Topic created in the ApsaraMQ for RocketMQ console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<YOUR_TOPIC>");
        // TCP endpoint of your instance.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.NAMESRV_ADDR, "<YOUR_TCP_ENDPOINT>");
        // Log path.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.LogPath, "C://log");

        // Create the producer instance.
        // A producer instance is thread-safe and can send messages to different topics.
        // Typically, one producer instance per thread is sufficient.
        Producer producer = ONSFactory.getInstance().createProducer(factoryInfo);

        // Start the producer.
        producer.start();

        // Build and send the message.
        Message msg = new Message(factoryInfo.getPublishTopics(), "tagA", "Example message body");
        msg.setKey(Guid.NewGuid().ToString());
        for (int i = 0; i < 32; i++) {
            try
            {
                SendResultONS sendResult = producer.send(msg);
                Console.WriteLine("send success {0}", sendResult.getMessageId());
            }
            catch (Exception ex)
            {
                Console.WriteLine("send failure{0}", ex.ToString());
            }
        }

        // Shut down the producer before exiting the thread.
        producer.shutdown();
    }
}

Saída esperada:

send success <message-id>
send success <message-id>
...

C/C++

O exemplo em C/C++ envia uma mensagem de forma síncrona com tratamento de exceções.

#include "ONSFactory.h"
#include "ONSClientException.h"

using namespace ons;

int main()
{
    // Configure the producer.
    ONSFactoryProperty factoryInfo;
    // Group ID created in the ApsaraMQ for RocketMQ console.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::ProducerId, "<YOUR_GROUP_ID>");
    // TCP endpoint of your instance.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "<YOUR_TCP_ENDPOINT>");
    // Topic created in the ApsaraMQ for RocketMQ console.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::PublishTopics, "<YOUR_TOPIC>");
    // Message content.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::MsgContent, "Hello MQ");
    // AccessKey ID for authentication.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, "<YOUR_ACCESS_KEY>");
    // AccessKey secret for authentication.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, "<YOUR_SECRET_KEY>");

    // Create the producer.
    Producer *pProducer = ONSFactory::getInstance()->createProducer(factoryInfo);

    // Call start() once before sending messages.
    pProducer->start();

    Message msg(
            // Topic for the message.
            factoryInfo.getPublishTopics(),
            // Message tag for filtering on the broker.
            "TagA",
            // Message body. Cannot be empty.
            // Producer and consumer must agree on serialization and deserialization.
            factoryInfo.getMessageContent()
    );

    // Message key: a business-specific identifier, ideally globally unique.
    // Useful for querying or resending messages in the console if delivery fails.
    // Messages can be sent without a key.
    msg.setKey("ORDERID_100");

    // Send the message. If no exception is thrown, the send succeeded.
    try
    {
        SendResultONS sendResult = pProducer->send(msg);
    }
    catch(ONSClientException & e)
    {
        // Handle the exception: log the error or retry.
    }

    // Shut down the producer before exiting.
    // Failing to shut down may cause memory leaks.
    pProducer->shutdown();

    return 0;
}
Nota

Para iniciar sua instância pelo console, abra o console do ApsaraMQ for RocketMQ, localize a instância, clique em More na coluna Actions e selecione Quick Start.

Para enviar e receber mensagens rapidamente, execute as seguintes etapas: faça login no console do ApsaraMQ for RocketMQ, localize o tópico criado e clique em More na coluna Actions. Na lista suspensa, selecione Quick Start. No painel exibido, escolha Console ou Docker.

Verificar se as mensagens foram enviadas

Após enviar uma mensagem, verifique seu status no console do ApsaraMQ for RocketMQ executando as operações abaixo:

  1. Na página Instance Details, clique em Message Query no painel de navegação à esquerda.

  2. Na página Message Query, escolha um método de consulta, especifique os parâmetros necessários e clique em Search.

    O campo Stored At indica o momento em que o broker do ApsaraMQ for RocketMQ armazenou a mensagem. Se for possível consultar a mensagem, ela foi enviada ao broker do Message Queue for Apache RocketMQ.

Importante

Esta etapa demonstra o cenário em que

o ApsaraMQ for RocketMQ

é utilizado pela primeira vez e o consumer ainda não foi iniciado. Portanto, nenhum dado de consumo aparece no console. Para iniciar o consumer e assinar mensagens, consulte a próxima seção. Para obter mais informações sobre o status da mensagem, veja

Message query

e

Query message traces

.

Etapa 3: Verificar a entrega da mensagem

Depois de enviar uma mensagem, confirme a entrega no console do ApsaraMQ for RocketMQ:

  1. Abra a página Instance Details e clique em Message Query no painel de navegação à esquerda.

  2. Na página Message Query, selecione um método de consulta, especifique os parâmetros obrigatórios e clique em Search.

Se a mensagem aparecer nos resultados, ela foi entregue ao broker do ApsaraMQ for RocketMQ. A coluna Stored At mostra quando o broker armazenou a mensagem.

Nota

O consumer ainda não foi iniciado, portanto, não há dados de consumo visíveis. Prossiga para a próxima etapa para iniciar o consumer. Para detalhes sobre o status da mensagem, consulte Query messages e Query message traces.

Etapa 4: Assinar mensagens normais

Após confirmar a entrega da mensagem, inicie um consumer para assinar as mensagens. Substitua os placeholders pelos valores reais e execute o código de exemplo.

Java

O consumer em Java assina mensagens de um ou mais tópicos. Filtre por tags específicas usando a sintaxe "TagA||TagB" ou use "*" para receber todas as tags.

import com.aliyun.openservices.ons.api.Action;
import com.aliyun.openservices.ons.api.ConsumeContext;
import com.aliyun.openservices.ons.api.Consumer;
import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.MessageListener;
import com.aliyun.openservices.ons.api.ONSFactory;
import com.aliyun.openservices.ons.api.PropertyKeyConst;

import java.util.Properties;

public class ConsumerTest {
   public static void main(String[] args) {
       Properties properties = new Properties();
       // Group ID created in the ApsaraMQ for RocketMQ console.
       properties.put(PropertyKeyConst.GROUP_ID, "<YOUR_GROUP_ID>");
       // AccessKey ID for authentication.
       properties.put(PropertyKeyConst.AccessKey, "<YOUR_ACCESS_KEY>");
       // AccessKey secret for authentication.
       properties.put(PropertyKeyConst.SecretKey, "<YOUR_SECRET_KEY>");
       // TCP endpoint of your instance.
       properties.put(PropertyKeyConst.NAMESRV_ADDR, "<YOUR_TCP_ENDPOINT>");

       // Consumption mode (optional):
       // Clustering (default): each message is delivered to one consumer in the group.
       // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING);
       // Broadcasting: each message is delivered to every consumer in the group.
       // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.BROADCASTING);

       Consumer consumer = ONSFactory.createConsumer(properties);

       // Subscribe to specific tags on a topic.
       consumer.subscribe("<YOUR_TOPIC>", "TagA||TagB", new MessageListener() {
           public Action consume(Message message, ConsumeContext context) {
               System.out.println("Receive: " + message);
               return Action.CommitMessage;
           }
       });

       // Subscribe to another topic with all tags.
       // To unsubscribe, remove the subscription code and restart the consumer.
       consumer.subscribe("TopicTestMQ-Other", "*", new MessageListener() {
           public Action consume(Message message, ConsumeContext context) {
               System.out.println("Receive: " + message);
               return Action.CommitMessage;
           }
       });

       consumer.start();
       System.out.println("Consumer Started");
   }
}

Saída esperada:

Consumer Started
Receive: <message-details>

.NET

O consumer em .NET usa um push consumer com um listener de mensagens personalizado.

using System;
using System.Threading;
using System.Text;
using ons;

// Message listener invoked when a message is pulled from the broker.
public class MyMsgListener : MessageListener
{
    public MyMsgListener()
    {
    }

    ~MyMsgListener()
    {
    }

    public override ons.Action consume(Message value, ConsumeContext context)
    {
        Byte[] text = Encoding.Default.GetBytes(value.getBody());
        Console.WriteLine(Encoding.UTF8.GetString(text));
        return ons.Action.CommitMessage;
    }
}

public class ConsumerExampleForEx
{
    public ConsumerExampleForEx()
    {
    }

    static void Main(string[] args) {
        ONSFactoryProperty factoryInfo = new ONSFactoryProperty();
        // AccessKey ID for authentication.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.AccessKey, "<YOUR_ACCESS_KEY>");
        // AccessKey secret for authentication.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.SecretKey, "<YOUR_SECRET_KEY>");
        // Group ID created in the ApsaraMQ for RocketMQ console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.ConsumerId, "<YOUR_GROUP_ID>");
        // Topic created in the ApsaraMQ for RocketMQ console.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.PublishTopics, "<YOUR_TOPIC>");
        // TCP endpoint of your instance.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.NAMESRV_ADDR, "<YOUR_TCP_ENDPOINT>");
        // Log path.
        factoryInfo.setFactoryProperty(ONSFactoryProperty.LogPath, "C://log");

        // Consumption mode (optional):
        // Clustering (default): each message is delivered to one consumer in the group.
        // factoryInfo.setFactoryProperty(ONSFactoryProperty:: MessageModel, ONSFactoryProperty.CLUSTERING);
        // Broadcasting: each message is delivered to every consumer in the group.
        // factoryInfo.setFactoryProperty(ONSFactoryProperty:: MessageModel, ONSFactoryProperty.BROADCASTING);

        // Create the push consumer instance.
        PushConsumer consumer = ONSFactory.getInstance().createPushConsumer(factoryInfo);

        // Subscribe to the topic with all tags.
        consumer.subscribe(factoryInfo.getPublishTopics(), "*", new MyMsgListener());

        // Start the consumer.
        consumer.start();

        // Keep the process alive to receive messages. In production, do not exit.
        Thread.Sleep(300000);

        // Shut down the consumer before exiting.
        consumer.shutdown();
    }
}

C/C++

O consumer em C/C++ usa um push consumer com um callback de listener de mensagens.

#include "ONSFactory.h"
using namespace ons;

// Message listener that processes each received message.
class MyMsgListener : public MessageListener
{
    public:
        MyMsgListener()
        {
        }

        virtual ~MyMsgListener()
        {
        }

        virtual Action consume(Message &message, ConsumeContext &context)
        {
            // Add your message processing logic here.
            return CommitMessage;
        }
};

int main(int argc, char* argv[])
{
    // Configure the push consumer.
    ONSFactoryProperty factoryInfo;
    // Group ID created in the ApsaraMQ for RocketMQ console.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::ConsumerId, "<YOUR_GROUP_ID>");
    // TCP endpoint of your instance.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::NAMESRV_ADDR, "<YOUR_TCP_ENDPOINT>");
    // Topic created in the ApsaraMQ for RocketMQ console.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::PublishTopics, "<YOUR_TOPIC>");
    // AccessKey ID for authentication.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::AccessKey, "<YOUR_ACCESS_KEY>");
    // AccessKey secret for authentication.
    factoryInfo.setFactoryProperty(ONSFactoryProperty::SecretKey, "<YOUR_SECRET_KEY>");

    // Consumption mode (optional):
    // Clustering (default): each message is delivered to one consumer in the group.
    // factoryInfo.setFactoryProperty(ONSFactoryProperty:: MessageModel, ONSFactoryProperty::CLUSTERING);
    // Broadcasting: each message is delivered to every consumer in the group.
    // factoryInfo.setFactoryProperty(ONSFactoryProperty:: MessageModel, ONSFactoryProperty::BROADCASTING);

    // Create the push consumer.
    PushConsumer* pushConsumer = ONSFactory::getInstance()->createPushConsumer(factoryInfo);

    // Subscribe to the topic and register the message listener.
    MyMsgListener msglistener;
    pushConsumer->subscribe(factoryInfo.getPublishTopics(), "*", &msglistener);

    // Start the push consumer.
    pushConsumer->start();

    // Keep the process alive to receive messages.
    // Call shutdown() only when the consumer is idle (not processing messages).
    // Failing to shut down may cause memory leaks.
    pushConsumer->shutdown();
    return 0;
}

Etapa 5: Verificar a assinatura

Após iniciar o consumer, verifique o status da assinatura:

  1. Abra a página Instance Details da sua instância e clique em Groups no painel de navegação à esquerda.

  2. Na página Groups, clique na aba TCP.

  3. Localize seu Group ID e clique em Details na coluna Actions.

A assinatura funciona corretamente quando:

  • O Consumer Status estiver como Online.

  • O campo Is Subscription Consistent estiver como Yes.

Referência de configuração

Parâmetros do producer

Parâmetro

Descrição

Obrigatório

AccessKey

AccessKey ID para autenticação

Sim

SecretKey

AccessKey secret para autenticação

Sim

NAMESRV_ADDR

Endpoint tcp da sua instância

Sim

SendMsgTimeoutMillis

Tempo limite de envio em milissegundos (valor de exemplo: 3000)

Não

ProducerId

Group ID (apenas .NET e C/C++)

Sim

PublishTopics

Nome do tópico (apenas .NET e C/C++)

Sim

LogPath

Caminho do arquivo de log (apenas .NET)

Não

Parâmetros do consumer

Parâmetro

Descrição

Obrigatório

AccessKey

AccessKey ID para autenticação

Sim

SecretKey

AccessKey secret para autenticação

Sim

NAMESRV_ADDR

Endpoint tcp da sua instância

Sim

GROUP_ID / ConsumerId

Group ID (Java usa GROUP_ID; .NET e C/C++ usam ConsumerId)

Sim

MessageModel

Modo de consumo: CLUSTERING (padrão) ou BROADCASTING

Não

PublishTopics

Nome do tópico (apenas .NET e C/C++)

Sim

LogPath

Caminho do arquivo de log (apenas .NET)

Não

Propriedades da mensagem

Propriedade

Descrição

Obrigatório

Topic

Tópico ao qual a mensagem pertence

Sim

Tag

Rótulo para filtragem de mensagens no broker. Os consumers filtram por tag ao assinar.

Não

Body

Payload da mensagem em formato binário. O producer e o consumer devem usar os mesmos métodos de serialização e desserialização.

Sim

Key

Identificador específico do negócio, idealmente único globalmente. Auxilia na consulta e no reenvio de mensagens com falha pelo console.

Não

Próximos passos