All Products
Search
Document Center

ApsaraMQ for MQTT:Export data from ApsaraMQ for MQTT to ApsaraMQ for RocketMQ

Last Updated:Aug 28, 2026

Data outbound rules forward messages from ApsaraMQ for MQTT to ApsaraMQ for RocketMQ. This lets backend applications consume MQTT messages with RocketMQ-native features such as ordered messages and transactional messages.

Currently, ApsaraMQ for MQTT supports data exchange only with ApsaraMQ for RocketMQ. This tutorial walks through two tasks: creating a data outbound rule in the console, and running a Java sample that publishes messages through MQTT over the Internet and consumes them from RocketMQ.

How it works

The data export flow has three stages:

  1. MQTT client publishes a message. A device or application connects to ApsaraMQ for MQTT and publishes a message to an MQTT topic (for example, sensor/temperature).

  2. Data outbound rule forwards the message. ApsaraMQ for MQTT matches the message against configured data outbound rules and forwards it to the mapped ApsaraMQ for RocketMQ topic.

  3. RocketMQ consumer receives the message. A backend application subscribes to the RocketMQ topic and processes the forwarded message using RocketMQ features such as message tracing and retry.

Architecture diagram

Limitations

  • Data outbound rules support only ApsaraMQ for RocketMQ 4.x instances as the destination.

  • Cross-region forwarding is not supported. The MQTT instance and the RocketMQ instance must be in the same region.

Network access

ApsaraMQ for MQTT provides two types of endpoints:

Endpoint typeUse case
Public EndpointAccess over the Internet. Typically used for IoT and mobile devices.
VPC EndpointAccess within a virtual private cloud (VPC). Typically used for cloud applications.
Important

Always use the domain name, not the resolved IP address, to connect clients. IP addresses change dynamically during domain name resolution updates. ApsaraMQ for MQTT is not liable for faults and direct or indirect losses caused by using hardcoded IP addresses or firewall rules based on IP addresses.

Prerequisites

Before you begin, make sure that you have:

Step 1: Create a data outbound rule

  1. Log on to the ApsaraMQ for MQTT console. In the left-side navigation pane, click Instances.

  2. In the top navigation bar, select the region of your instance. Click the instance name to open the Instance Details page.

  3. In the left-side navigation pane, click Rules. In the upper-left corner, click Create Rule.

  4. Complete the Create Rule wizard:

    1. Configure Basic Information: Enter a rule ID and set Rule Type to Data Outbound.

      Configure basic information

    2. Configure Rule Source: Select a topic on your ApsaraMQ for MQTT instance.

      Configure rule source

    3. Configure Rule Destination: Select your ApsaraMQ for RocketMQ instance and a topic on that instance.

      Configure rule destination

Step 2: Set up the sample project

Download the sample code

  1. Clone or download the mqtt-java-demo project.

  2. Open the lmq-java-demo folder in IntelliJ IDEA.

  3. Verify that your pom.xml includes the following dependencies:

<dependencies>
    <dependency>
        <groupId>org.bouncycastle</groupId>
        <artifactId>bcprov-jdk15on</artifactId>
        <version>1.70</version>
    </dependency>
    <dependency>
        <groupId>commons-codec</groupId>
        <artifactId>commons-codec</artifactId>
        <version>1.10</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.paho</groupId>
        <artifactId>org.eclipse.paho.client.mqttv3</artifactId>
        <version>1.2.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
        <version>4.5.2</version>
    </dependency>
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>fastjson</artifactId>
        <version>1.2.83</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun.openservices</groupId>
        <artifactId>ons-client</artifactId>
        <version>1.8.5.Final</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-onsmqtt</artifactId>
        <version>1.0.3</version>
    </dependency>
    <dependency>
        <groupId>com.aliyun</groupId>
        <artifactId>aliyun-java-sdk-core</artifactId>
        <version>4.5.0</version>
    </dependency>
</dependencies>

Configure access credentials

  1. Get an AccessKey pair. For details, see Create an AccessKey pair.

  2. Set the following environment variables. For details, see Configure an access credential.

    VariableDescription
    MQTT_AK_ENVAccessKey ID
    MQTT_SK_ENVAccessKey secret
Important

Do not hardcode AccessKey pairs in source code. Store them in environment variables to avoid accidental exposure.

Step 3: Run the sample code

The MQ4IoTSendMessageToRocketMQ.java class demonstrates the full data flow: it sends messages through ApsaraMQ for MQTT and consumes them through ApsaraMQ for RocketMQ. Before running the sample, replace the placeholder values with your resource information.

Replace the following placeholders:

PlaceholderDescriptionWhere to find it
GID-XXXXXRocketMQ group IDApsaraMQ for RocketMQ console
http://xxxxx.XXXXX.mq-internet.aliyuncs.comRocketMQ TCP endpointInstance Details page in the ApsaraMQ for RocketMQ console
XXXXX (parentTopic)RocketMQ topic nameApsaraMQ for RocketMQ console
XXXXX (instanceId)MQTT instance IDInstance Details page in the ApsaraMQ for MQTT console
XXXXXX.mqtt.aliyuncs.comMQTT endpointInstance Details page in the ApsaraMQ for MQTT console
GID_XXXX@@@XXXXXMQTT client ID (format: GroupID@@@DeviceID)Generate using your MQTT group ID and a unique device ID

Client ID requirements:

  • Format: GroupID@@@DeviceID. The group ID is the one created in the ApsaraMQ for MQTT console. The device ID is a custom identifier.

  • Maximum length: 64 characters.

  • Each TCP connection must use a unique client ID. Duplicate client IDs cause connection exceptions and unexpected disconnections.

Sample code

The sample code initializes a RocketMQ consumer that subscribes to a topic, creates an MQTT client that publishes 10 test messages to a subtopic, and relies on the data outbound rule to forward these messages to the RocketMQ topic for consumption.

import com.aliyun.openservices.lmq.example.util.ConnectionOptionWrapper;
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;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;
import org.eclipse.paho.client.mqttv3.MqttClient;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;

public class MQ4IoTSendMessageToRocketMQ {
    public static void main(String[] args) throws Exception {
        // ============================================================
        // 1. Initialize the RocketMQ consumer (backend application)
        // ============================================================
        Properties properties = new Properties();

        // RocketMQ group ID
        properties.setProperty(PropertyKeyConst.GROUP_ID, "GID-XXXXX");

        // Load credentials from environment variables
        properties.put(PropertyKeyConst.AccessKey, System.getenv("MQTT_AK_ENV"));
        properties.put(PropertyKeyConst.SecretKey, System.getenv("MQTT_SK_ENV"));

        // RocketMQ TCP endpoint (from the Instance Details page)
        properties.put(PropertyKeyConst.NAMESRV_ADDR,
            "http://xxxxx.XXXXX.mq-internet.aliyuncs.com");

        // RocketMQ topic (must be a parent topic for MQTT-RocketMQ data exchange)
        final String parentTopic = "XXXXX";

        Consumer consumer = ONSFactory.createConsumer(properties);
        consumer.subscribe(parentTopic, "*", new MessageListener() {
            public Action consume(Message message, ConsumeContext consumeContext) {
                System.out.println("recv msg:" + message);
                return Action.CommitMessage;
            }
        });
        consumer.start();

        // ============================================================
        // 2. Initialize the MQTT client (device or mobile app)
        // ============================================================

        // MQTT instance ID
        String instanceId = "XXXXX";

        // MQTT endpoint (from the Instance Details page)
        String endPoint = "XXXXXX.mqtt.aliyuncs.com";

        // Load credentials from environment variables
        String accessKey = System.getenv("MQTT_AK_ENV");
        String secretKey = System.getenv("MQTT_SK_ENV");

        // Client ID: GroupID@@@DeviceID (must be unique per TCP connection)
        String clientId = "GID_XXXX@@@XXXXX";

        // Subtopic: parentTopic + "/" + subtopic name (max 128 characters)
        final String mq4IotTopic = parentTopic + "/" + "testMq4Iot";

        // QoS level: 0, 1, or 2
        final int qosLevel = 0;

        ConnectionOptionWrapper connectionOptionWrapper =
            new ConnectionOptionWrapper(instanceId, accessKey, secretKey, clientId);
        final MemoryPersistence memoryPersistence = new MemoryPersistence();

        // Protocol and port: tcp://endpoint:1883 or ssl://endpoint:8883
        final MqttClient mqttClient =
            new MqttClient("tcp://" + endPoint + ":1883", clientId, memoryPersistence);

        // Client timeout in milliseconds
        mqttClient.setTimeToWait(5000);
        mqttClient.setCallback(new MqttCallbackExtended() {
            @Override
            public void connectComplete(boolean reconnect, String serverURI) {
                System.out.println("connect success");
            }

            @Override
            public void connectionLost(Throwable throwable) {
                throwable.printStackTrace();
            }

            @Override
            public void messageArrived(String s, MqttMessage mqttMessage) throws Exception {
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
                System.out.println("send msg succeed topic is : "
                    + iMqttDeliveryToken.getTopics()[0]);
            }
        });
        mqttClient.connect(connectionOptionWrapper.getMqttConnectOptions());

        // ============================================================
        // 3. Publish 10 test messages
        // ============================================================
        for (int i = 0; i < 10; i++) {
            MqttMessage message = new MqttMessage("hello mq4Iot pub sub msg".getBytes());
            message.setQos(qosLevel);
            mqttClient.publish(mq4IotTopic, message);
        }
        Thread.sleep(Long.MAX_VALUE);
    }
}

Step 4: Verify the result

After running the MQ4IoTSendMessageToRocketMQ class, verify end-to-end message delivery using either method below.

Check the code output

If the console output shows messages similar to the following, the MQTT client sent the messages and the RocketMQ consumer received them:

Code verification output

Check the console

Verify that messages were sent:

  1. Go to the Instance Details page in the ApsaraMQ for MQTT console.

  2. In the left-side navigation pane, click Message Trace Query.

  3. Search by group ID and device ID to confirm the messages were published.

Message Trace Query

Verify that messages were consumed:

  1. Go to the Instance Details page in the ApsaraMQ for RocketMQ console.

  2. In the left-side navigation pane, click Message Query.

  3. Search by topic to confirm the messages were forwarded to RocketMQ.

Message Query
  1. Click Message Trace in the Actions column to verify the message was consumed.

Message Trace details

What's next