Tüm Ürünler
Search
Belge Merkezi

ApsaraMQ for RocketMQ:Send and receive scheduled and delayed messages

Son Güncelleme:Oct 04, 2026

Bu konuda, Go için ApsaraMQ for RocketMQ HTTP istemci SDK'sını kullanarak zamanlanmış ve gecikmeli mesajların nasıl gönderileceği ve alınacağına ilişkin örnek kodlar sunulmaktadır.

Zamanlanmış ve gecikmeli mesajlar

Zamanlanmış ve gecikmeli mesajlar, bir mesajın tüketicilere ne zaman teslim edileceğini belirler:

  • Gecikmeli mesaj: Gönderildikten sonra belirtilen süre kadar bekletilip teslim edilir. Örneğin, bir mesajı şimdi gönderin ve 30 saniye sonra teslim edilmesini sağlayın.

  • Zamanlanmış mesaj: Belirli bir saatte teslim edilir. Örneğin, bir mesajı şimdi gönderin ve yarın saat 14:00'te teslim edilmesini sağlayın.

HTTP üzerinden her iki tür de aynı mekanizmayı kullanır: StartDeliverTime alanını milisaniye cinsinden gelecekteki bir Unix zaman damgasına ayarlayın. Broker, bu zaman damgasına gelene kadar mesajı bekletir ve ardından teslim eder.

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

Ön koşullar

Başlamadan önce aşağıdakileri tamamladığınızdan emin olun:

Çalışma biçimi

Hem zamanlanmış hem de gecikmeli mesajlar, teslim zamanlamasını kontrol etmek için StartDeliverTime alanını kullanır. Bu alanı, broker'ın mesajı teslim etmesi gereken zamanı temsil eden milisaniye cinsinden bir Unix zaman damgasına ayarlayın.

  • Gecikmeli teslim: İstenen gecikme süresini (milisaniye cinsinden) geçerli saate ekleyin.

      // Deliver 10 seconds from now
      msg.StartDeliverTime = time.Now().UTC().Unix() * 1000 + 10 * 1000
  • Zamanlanmış teslim: Hedef teslim saatini milisaniye cinsinden bir Unix zaman damgasına dönüştürün.

      // Deliver at a specific time
      msg.StartDeliverTime = targetTime.UTC().Unix() * 1000
Eğer StartDeliverTime geçerli zamandan daha eski bir zaman damgasına ayarlanırsa mesaj hemen teslim edilir.

Zamanlanmış ve gecikmeli mesajları gönderme

Aşağıdaki örnek, her biri gönderildikten 10 saniye sonra teslim edilmek üzere planlanmış dört gecikmeli mesaj gönderir.

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

Yer Tutucu Açıklama Örnek
${HTTP_ENDPOINT} Instance Details sayfasındaki HTTP Endpoint bölümünden alınan HTTP uç noktası http://1234567890.mqrest.cn-hangzhou.aliyuncs.com
${TOPIC} ApsaraMQ for RocketMQ konsolunda oluşturulan konu adı delayed-msg-topic
${INSTANCE_ID} Örnek Kimliği. Örneğin bir ad alanı varsa kimliği belirtin. Yoksa null veya boş bir dize olarak ayarlayın MQ_INST_1234567890_ABCDEF
package main

import (
    "fmt"
    "time"
    "strconv"
    "os"

    "github.com/aliyunmq/mq-http-go-sdk"
)

func main() {
    // HTTP endpoint from the HTTP Endpoint section of the Instance Details page in the ApsaraMQ for RocketMQ console.
    endpoint := "${HTTP_ENDPOINT}"
    // AccessKey pair from environment variables.
    accessKey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
    secretKey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
    // Topic created in the ApsaraMQ for RocketMQ console.
    topic := "${TOPIC}"
    // Instance ID. If the instance has a namespace, specify the ID.
    // If the instance does not have a namespace, set this to null or an empty string.
    // You can check the namespace on the Instance Details page in the ApsaraMQ for RocketMQ console.
    instanceId := "${INSTANCE_ID}"

    client := mq_http_sdk.NewAliyunMQClient(endpoint, accessKey, secretKey, "")

    mqProducer := client.GetProducer(instanceId, topic)
    // Cyclically send four messages.
    for i := 0; i < 4; i++ {
        var msg mq_http_sdk.PublishMessageRequest

            msg = mq_http_sdk.PublishMessageRequest{
            MessageBody: "hello mq!",         // The message content.
            MessageTag:  "",                  // The message tag.
            Properties:  map[string]string{}, // The message properties.
            }
        // The message key.
            msg.MessageKey = "MessageKey"
            // The custom properties of the message.
            msg.Properties["a"] = strconv.Itoa(i)
            // Deliver 10 seconds from now. Set to a Unix timestamp in milliseconds.
            // For scheduled delivery, set this to the time difference between the scheduled point and the current time.
            msg.StartDeliverTime = time.Now().UTC().Unix() * 1000 + 10 * 1000

        ret, err := mqProducer.PublishMessage(msg)

        if err != nil {
            fmt.Println(err)
            return
        } else {
            fmt.Printf("Publish ---->\n\tMessageId:%s, BodyMD5:%s, \n", ret.MessageId, ret.MessageBodyMD5)
        }
        time.Sleep(time.Duration(100) * time.Millisecond)
    }
}

Zamanlanmış ve gecikmeli mesajları alma

Aşağıdaki örnek, uzun oylama kullanarak zamanlanmış ve gecikmeli mesajları tüketir. Tüketici, yeni mesajlar için en fazla 3 saniye bekler ve toplu iş başına en fazla 3 mesajı işler.

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

Yer Tutucu Açıklama Örnek
${HTTP_ENDPOINT} Instance Details sayfasındaki HTTP Endpoint bölümünden alınan HTTP uç noktası http://1234567890.mqrest.cn-hangzhou.aliyuncs.com
${TOPIC} ApsaraMQ for RocketMQ konsolunda oluşturulan konu adı delayed-msg-topic
${INSTANCE_ID} Örnek Kimliği. Örneğin bir ad alanı varsa kimliği belirtin. Yoksa null veya boş bir dize olarak ayarlayın MQ_INST_1234567890_ABCDEF
${GROUP_ID} ApsaraMQ for RocketMQ konsolunda oluşturulan tüketici grubu kimliği GID_delayed_consumer
Her konu yalnızca bir mesaj türünü destekler. Zamanlanmış veya gecikmeli mesajlar için kullanılan bir konu, diğer mesaj türlerini gönderemez veya alamaz.
package main

import (
    "fmt"
    "github.com/gogap/errors"
    "strings"
    "time"
    "os"

    "github.com/aliyunmq/mq-http-go-sdk"
)

func main() {
    // HTTP endpoint from the HTTP Endpoint section of the Instance Details page in the ApsaraMQ for RocketMQ console.
    endpoint := "${HTTP_ENDPOINT}"
    // AccessKey pair from environment variables.
    accessKey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_ID")
    secretKey := os.Getenv("ALIBABA_CLOUD_ACCESS_KEY_SECRET")
    // Topic created in the ApsaraMQ for RocketMQ console.
    // Each topic can only send and receive messages of a specific type.
    topic := "${TOPIC}"
    // Instance ID. If the instance has a namespace, specify the ID.
    // If the instance does not have a namespace, set this to null or an empty string.
    // You can check the namespace on the Instance Details page in the ApsaraMQ for RocketMQ console.
    instanceId := "${INSTANCE_ID}"
    // Consumer group ID created in the ApsaraMQ for RocketMQ console.
    groupId := "${GROUP_ID}"

    client := mq_http_sdk.NewAliyunMQClient(endpoint, accessKey, secretKey, "")

    mqConsumer := client.GetConsumer(instanceId, topic, groupId, "")

    for {
        endChan := make(chan int)
        respChan := make(chan mq_http_sdk.ConsumeMessageResponse)
        errChan := make(chan error)
        go func() {
            select {
            case resp := <-respChan:
                {
                    // The message consumption logic.
                    var handles []string
                    fmt.Printf("Consume %d messages---->\n", len(resp.Messages))
                    for _, v := range resp.Messages {
                        handles = append(handles, v.ReceiptHandle)
                        fmt.Printf("\tMessageID: %s, PublishTime: %d, MessageTag: %s\n"+
                            "\tConsumedTimes: %d, FirstConsumeTime: %d, NextConsumeTime: %d\n"+
                            "\tBody: %s\n"+
                            "\tProps: %s\n",
                            v.MessageId, v.PublishTime, v.MessageTag, v.ConsumedTimes,
                            v.FirstConsumeTime, v.NextConsumeTime, v.MessageBody, v.Properties)
                    }

                    // If the broker does not receive an acknowledgment (ACK) before the NextConsumeTime
                    // elapses, the message is redelivered to the consumer.
                    // A unique timestamp is specified for the handle each time the message is consumed.
                    ackerr := mqConsumer.AckMessage(handles)
                    if ackerr != nil {
                        // If the handle times out, the broker fails to receive an ACK from the consumer.
                        fmt.Println(ackerr)
                        if errAckItems, ok := ackerr.(errors.ErrCode).Context()["Detail"].([]mq_http_sdk.ErrAckItem); ok {
                           for _, errAckItem := range errAckItems {
                             fmt.Printf("\tErrorHandle:%s, ErrorCode:%s, ErrorMsg:%s\n",
                               errAckItem.ErrorHandle, errAckItem.ErrorCode, errAckItem.ErrorMsg)
                           }
                        } else {
                           fmt.Println("ack err =", ackerr)
                        }
                        time.Sleep(time.Duration(3) * time.Second)
                    } else {
                        fmt.Printf("Ack ---->\n\t%s\n", handles)
                    }

                    endChan <- 1
                }
            case err := <-errChan:
                {
                    // No message is available for consumption in the topic.
                    if strings.Contains(err.(errors.ErrCode).Error(), "MessageNotExist") {
                        fmt.Println("\nNo new message, continue!")
                    } else {
                        fmt.Println(err)
                        time.Sleep(time.Duration(3) * time.Second)
                    }
                    endChan <- 1
                }
            case <-time.After(35 * time.Second):
                {
                    fmt.Println("Timeout of consumer message ??")
                    endChan <- 1
                }
            }
        }()

        // Long polling: the default network timeout is 35 seconds.
        // If no message is available, the request is suspended on the broker for the specified period.
        // If a message becomes available during the wait, the broker responds immediately.
        mqConsumer.ConsumeMessage(respChan, errChan,
            3, // Maximum number of messages per batch (max: 16).
            3, // Long polling wait time in seconds (max: 30).
        )
        <-endChan
    }
}

Sonraki adımlar