All Products
Search
Document Center

ApsaraMQ for RocketMQ:Send normal messages in synchronous, asynchronous, or one-way mode

Last Updated:Mar 11, 2026

ApsaraMQ for RocketMQ supports three transmission modes for normal messages. Choose a mode based on how much delivery guarantee your application requires:

ModeBehaviorBest for
SynchronousThe producer waits for a broker acknowledgment before sending the next message.Scenarios that require delivery confirmation
AsynchronousThe producer sends a message and moves on immediately. A callback returns the result.Latency-sensitive workflows
One-wayThe producer sends a message without expecting any response.High-throughput scenarios where occasional message loss is acceptable

Prerequisites

Before you begin, make sure that you have:

Common producer setup

All three modes share the same initialization logic. Create a producer once, then call the mode-specific send method.

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

import java.util.Date;
import java.util.Properties;
import java.util.concurrent.TimeUnit;

Properties properties = new Properties();
// Read credentials from environment variables.
properties.put(PropertyKeyConst.AccessKey, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"));
properties.put(PropertyKeyConst.SecretKey, System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET"));
// Send timeout in milliseconds.
properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000");
// TCP endpoint. Find this in the TCP Endpoint section of the Instance Details page
// in the ApsaraMQ for RocketMQ console.
properties.put(PropertyKeyConst.NAMESRV_ADDR, "<your-tcp-endpoint>");

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

Replace the placeholder with your actual value:

PlaceholderDescriptionExample
<your-tcp-endpoint>The TCP endpoint of your instancehttp://MQ_INST_xxxxx.mq-internet.region.aliyuncs.com:80

Build a message

Every send call requires a Message object. The constructor takes three arguments:

Message msg = new Message(
    "TopicTestMQ",          // Topic -- must be a normal-message topic
    "TagA",                 // Tag -- used by consumers to filter messages
    "Hello MQ".getBytes()   // Body -- binary payload; producer and consumer must
                            // agree on the serialization format
);

// Optional: set a business key for message tracing in the console.
msg.setKey("ORDERID_100");
A topic used for normal messages cannot be used for other message types such as transactional or scheduled messages.

Synchronous transmission

The producer sends a message and blocks until the broker returns a response. If no exception is thrown, the message was delivered successfully.

Synchronous transmission

When to use: Scenarios that require delivery confirmation, such as email notifications, sign-up alerts, or promotional messages.

Sample code

for (int i = 0; i < 100; i++) {
    Message msg = new Message("TopicTestMQ", "TagA", "Hello MQ".getBytes());
    msg.setKey("ORDERID_" + i);

    try {
        SendResult sendResult = producer.send(msg);
        // A non-null result means the broker accepted the message.
        if (sendResult != null) {
            System.out.println(new Date() + " Send mq message success. Topic is:"
                + msg.getTopic() + " msgId is: " + sendResult.getMessageId());
        }
    } catch (Exception e) {
        // Handle failures: retry or persist the message for later delivery.
        System.out.println(new Date() + " Send mq message failed. Topic is:" + msg.getTopic());
        e.printStackTrace();
    }
}

Asynchronous transmission

The producer sends a message and returns immediately. The broker response is delivered through a SendCallback with two methods: onSuccess and onException.

Asynchronous transmission

When to use: Latency-sensitive workflows where the calling thread cannot block -- for example, submitting a video transcoding job and handling the result in a callback.

Sample code

Message msg = new Message("TopicTestMQ", "TagA", "Hello MQ".getBytes());
msg.setKey("ORDERID_100");

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 failures: retry or persist the message for later delivery.
        System.out.println("send message failed. topic=" + context.getTopic()
            + ", msgId=" + context.getMessageId());
    }
});

// Block for 3 seconds to wait for the callback. In production, use a
// CountDownLatch or similar mechanism instead of Thread.sleep.
TimeUnit.SECONDS.sleep(3);

One-way transmission

The producer fires a message and moves on. No response is returned and no callback is triggered. This mode delivers the highest throughput at the cost of reliability -- a message can be sent within microseconds.

One-way transmission

When to use: High-volume scenarios where occasional message loss is acceptable, such as log collection or metrics reporting.

Warning

The broker does not send a response in one-way mode, so failed messages are silently lost. If data loss is not acceptable, use synchronous or asynchronous transmission instead.

Sample code

for (int i = 0; i < 100; i++) {
    Message msg = new Message("TopicTestMQ", "TagA", "Hello MQ".getBytes());
    msg.setKey("ORDERID_" + i);

    // No return value, no callback. Fire and forget.
    producer.sendOneway(msg);
}

Shut down the producer

Shut down the producer before your application exits to free resources.

producer.shutdown();
Shutting down the producer frees memory. If your application sends messages frequently, keep the producer running instead of creating and destroying it per request.

Comparison of transmission modes

The three modes differ in whether the producer waits for a broker response and the trade-off between throughput and reliability.

ModeSend methodTPSBroker responseReliabilityTypical use case
Synchronousproducer.send(msg)HighYes -- the producer blocks until the broker acknowledges the messageNo message lossNotifications, order confirmations
Asynchronousproducer.sendAsync(msg, callback)HighYes -- delivered through SendCallbackNo message lossVideo transcoding, async workflows
One-wayproducer.sendOneway(msg)HighestNo -- the broker does not respond, so the producer cannot detect failuresPossible message lossLog collection, metrics

What's next