Tüm Ürünler
Search
Belge Merkezi

ApsaraMQ for RocketMQ:Send and consume scheduled or delayed messages

Son Güncelleme:Oct 04, 2026

Bu konuda, ApsaraMQ for RocketMQ HTTP istemci SDK aracılığıyla zamanlanmış veya gecikmeli mesajların nasıl gönderileceği ve tüketileceğine ilişkin Java örnek kodları sunulmaktadır.

Zamanlanmış ve gecikmeli mesajlar arasındaki farklar

API düzeyinde zamanlanmış mesajlar ile gecikmeli mesajlar aynı özelliği kullanır. Her ikisi de teslimatı ertelemek için setStartDeliverTime yöntemini çağırır. Aralarındaki tek fark, zaman damgasının nasıl hesaplandığıdır:

Tür Teslimat zamanını ayarlama yöntemi Örnek
Gecikmeli mesaj Geçerli saat + ofset System.currentTimeMillis() + 10 * 1000 (10 saniyelik gecikme)
Zamanlanmış mesaj Milisaniye cinsinden mutlak Unix zaman damgası 1654770600000 (2022-06-09 18:30:00)

Broker, her mesajı belirtilen teslimat zamanına kadar bekletir ve ardından tüketim için serbest bırakır. Bu ayar mesaj başına yapılır; dolayısıyla her mesajın kendi teslimat zamanı olabilir.

Daha fazla bilgi için bkz. Zamanlanmış mesajlar ve gecikmeli mesajlar.

Önkoşullar

Başlamadan önce aşağıdaki adımları tamamladığınızdan emin olun:

Önemli

Her konu yalnızca bir mesaj türünü destekler. Normal mesajlar için yapılandırdığınız bir konuyu, zamanlanmış veya gecikmeli mesajlar göndermek amacıyla yeniden kullanmayın.

Zamanlanmış veya gecikmeli mesajları gönderme

Bu örnekteki tüm mesajlar, teslimatı 10 saniye ertelemek için setStartDeliverTime yöntemini kullanır. Zamanlanmış bir mesaj göndermek için göreli ofset yerine milisaniye cinsinden mutlak bir Unix zaman damgası belirtin (örneğin, 2022-06-09 18:30:00 için 1654770600000).

import com.aliyun.mq.http.MQClient;
import com.aliyun.mq.http.MQProducer;
import com.aliyun.mq.http.model.TopicMessage;

import java.util.Date;

public class Producer {

    public static void main(String[] args) {
        MQClient mqClient = new MQClient(
                // HTTP endpoint. Find this on the Instance Details page, in the
                // Endpoints tab under Basic Information.
                "<your-http-endpoint>",
                // Load credentials from environment variables to avoid hardcoding secrets.
                System.getenv("ALIBABA_CLOUD_ACCESS_KEY_ID"),
                System.getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
        );

        final String topic = "<your-topic>";
        // If the instance has a namespace, specify the instance ID.
        // If it does not have a namespace, set this to null or "".
        final String instanceId = "<your-instance-id>";

        MQProducer producer;
        if (instanceId != null && instanceId != "") {
            producer = mqClient.getProducer(instanceId, topic);
        } else {
            producer = mqClient.getProducer(topic);
        }

        try {
            for (int i = 0; i < 4; i++) {
                TopicMessage pubMsg = new TopicMessage(
                        "hello mq!".getBytes(),   // Message body
                        "A"                        // Message tag
                );
                pubMsg.getProperties().put("a", String.valueOf(i));  // Custom property
                pubMsg.setMessageKey("MessageKey");

                // Defer delivery by 10 seconds.
                // For a scheduled message, use an absolute timestamp instead,
                // e.g., pubMsg.setStartDeliverTime(1654770600000L);
                pubMsg.setStartDeliverTime(System.currentTimeMillis() + 10 * 1000);

                TopicMessage pubResultMsg = producer.publishMessage(pubMsg);

                System.out.println(new Date() + " Send mq message success."
                        + " Topic is:" + topic
                        + ", msgId is: " + pubResultMsg.getMessageId()
                        + ", bodyMD5 is: " + pubResultMsg.getMessageBodyMD5());
            }
        } catch (Throwable e) {
            System.out.println(new Date() + " Send mq message failed. Topic is:" + topic);
            e.printStackTrace();
        }

        mqClient.close();
    }
}

Aşağıdaki yer tutucuları gerçek değerlerinizle değiştirin:

Yer Tutucu Açıklama Nerede Bulunur
<your-http-endpoint> HTTP uç noktası Örnek Ayrıntıları sayfası > Endpoints sekmesi > HTTP Endpoint
<your-topic> Konu adı ApsaraMQ for RocketMQ konsolu > Topics
<your-instance-id> Örnek Kimliği veya örneğin ad alanı yoksa null Örnek Ayrıntıları sayfası > Basic Information

Zamanlanmış veya gecikmeli mesajları tüketme

Zamanlanmış ve gecikmeli mesajları normal mesajlarla aynı şekilde tüketin. Broker, teslimat zamanı gelene kadar mesajları bekletir ve ardından bunları tüketim için serbest bırakır.

Aşağıdaki örnekte uzun yoklama (long polling) kullanılarak mesajlar tüketilir ve broker'a onaylar (ACK'ler) gönderilir.

import com.aliyun.mq.http.MQClient;
import com.aliyun.mq.http.MQConsumer;
import com.aliyun.mq.http.common.AckMessageException;
import com.aliyun.mq.http.model.Message;

import java.util.ArrayList;
import java.util.List;

public class Consumer {

    public static void main(String[] args) {
        MQClient mqClient = new MQClient(
                // HTTP endpoint. Find this on the Instance Details page, in the
                // Endpoints tab under Basic Information.
                "<your-http-endpoint>",
                // The AccessKey ID for authentication.
                "${ACCESS_KEY}",
                // The AccessKey secret for authentication.
                "${SECRET_KEY}"
        );

        final String topic = "<your-topic>";
        final String groupId = "<your-group-id>";
        // If the instance has a namespace, specify the instance ID.
        // If it does not have a namespace, set this to null or "".
        final String instanceId = "<your-instance-id>";

        final MQConsumer consumer;
        if (instanceId != null && instanceId != "") {
            consumer = mqClient.getConsumer(instanceId, topic, groupId, null);
        } else {
            consumer = mqClient.getConsumer(topic, groupId);
        }

        // Consume messages in a loop. For production use, run multiple threads
        // to consume messages concurrently.
        do {
            List<Message> messages = null;

            try {
                // Long polling: wait up to 3 seconds for new messages.
                // - First parameter: max messages per batch (max: 16).
                // - Second parameter: long polling timeout in seconds (max: 30).
                messages = consumer.consumeMessage(3, 3);
            } catch (Throwable e) {
                e.printStackTrace();
                try {
                    Thread.sleep(2000);
                } catch (InterruptedException e1) {
                    e1.printStackTrace();
                }
            }

            if (messages == null || messages.isEmpty()) {
                System.out.println(Thread.currentThread().getName()
                        + ": no new message, continue!");
                continue;
            }

            // Process messages
            for (Message message : messages) {
                System.out.println("Receive message: " + message);
            }

            // ACK consumed messages. If the broker does not receive an ACK
            // before the retry interval elapses, the message is redelivered.
            {
                List<String> handles = new ArrayList<String>();
                for (Message message : messages) {
                    handles.add(message.getReceiptHandle());
                }

                try {
                    consumer.ackMessage(handles);
                } catch (Throwable e) {
                    if (e instanceof AckMessageException) {
                        AckMessageException errors = (AckMessageException) e;
                        System.out.println("Ack message fail, requestId is:"
                                + errors.getRequestId() + ", fail handles:");
                        if (errors.getErrorMessages() != null) {
                            for (String errorHandle : errors.getErrorMessages().keySet()) {
                                System.out.println("Handle:" + errorHandle
                                        + ", ErrorCode:" + errors.getErrorMessages().get(errorHandle).getErrorCode()
                                        + ", ErrorMsg:" + errors.getErrorMessages().get(errorHandle).getErrorMessage());
                            }
                        }
                        continue;
                    }
                    e.printStackTrace();
                }
            }
        } while (true);
    }
}

Aşağıdaki yer tutucuları gerçek değerlerinizle değiştirin:

Yer Tutucu Açıklama Nerede Bulunur
<your-http-endpoint> HTTP uç noktası Örnek Ayrıntıları sayfası > Endpoints sekmesi > HTTP Endpoint
${ACCESS_KEY} Kimlik doğrulama için AccessKey kimliği Bkz. AccessKey çifti oluşturma
${SECRET_KEY} Kimlik doğrulama için AccessKey gizli anahtarı Bkz. AccessKey çifti oluşturma
<your-topic> Konu adı ApsaraMQ for RocketMQ konsolu > Topics
<your-group-id> Tüketici grubu kimliği ApsaraMQ for RocketMQ konsolu > Groups
<your-instance-id> Örnek Kimliği veya örneğin ad alanı yoksa null Örnek Ayrıntıları sayfası > Basic Information

Sonraki adımlar