Todos os produtos
Search
Central de documentação

ApsaraMQ for RocketMQ:Send and receive scheduled and delayed messages

Última atualização: Jun 27, 2026

Use o SDK do cliente HTTP Python para enviar e receber mensagens agendadas e atrasadas no ApsaraMQ for RocketMQ. Este tópico apresenta exemplos completos de código para produtor e consumidor.

Funcionamento das mensagens agendadas e atrasadas

Mensagens agendadas e atrasadas adiam a entrega aos consumidores até um momento específico:

  • Mensagem atrasada: entregue após um intervalo fixo. Por exemplo, uma mensagem com atraso de 10 segundos fica disponível para consumo 10 segundos após o envio.

  • Mensagem agendada: entregue em um ponto exato no tempo. Por exemplo, uma mensagem agendada para 2024-01-15 15:00:00 é entregue exatamente nesse horário.

Via HTTP, ambos os tipos usam a mesma API. Defina start_deliver_time como um timestamp Unix futuro em milissegundos:

  • Para mensagem atrasada, calcule o timestamp como current_time + delay_duration.

  • Para mensagem agendada, defina o timestamp diretamente como o horário de entrega desejado.

Para mais informações, consulte Scheduled messages and delayed messages.

Pré-requisitos

Antes de começar, verifique se você tem:

  • SDK do cliente HTTP Python instalado. Para detalhes, consulte Prepare the environment

  • Instância, tópico e grupo de consumidores do ApsaraMQ for RocketMQ criados no console do ApsaraMQ for RocketMQ. Para detalhes, consulte Create resources

  • Par de AccessKey da sua conta Alibaba Cloud. Para detalhes, consulte Create an AccessKey pair

Enviar mensagens agendadas ou atrasadas

O exemplo a seguir envia quatro mensagens atrasadas, cada uma entregue 10 segundos após o envio. Para enviar uma mensagem agendada, defina start_deliver_time como o horário de entrega alvo em timestamp Unix de milissegundos.

Substitua os espaços reservados a seguir pelos valores reais:

Espaço reservado

Descrição

Exemplo

<http-endpoint>

Endpoint HTTP da instância. Disponível na página Instance Details do console ApsaraMQ for RocketMQ

http://xxxxx.mqrest.cn-hangzhou.aliyuncs.com

<topic>

Nome do tópico de destino das mensagens

scheduled-msg-topic

<instance-id>

ID da instância proprietária do tópico. Obrigatório se a instância tiver namespace. Se não tiver, passe uma string vazia. Verifique o status do namespace na página Instance Details

MQ_INST_xxxxx

import sys
import os
import time

from mq_http_sdk.mq_exception import MQExceptionBase
from mq_http_sdk.mq_producer import *
from mq_http_sdk.mq_client import *

# Initialize the producer client
mq_client = MQClient(
    # HTTP endpoint. Find it in the HTTP Endpoint section
    # of the Instance Details page in the ApsaraMQ for RocketMQ console.
    "<http-endpoint>",
    # AccessKey ID and AccessKey secret for authentication.
    # Store credentials in environment variables instead of hardcoding them.
    os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
    os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
)

topic_name = "<topic>"
instance_id = "<instance-id>"

producer = mq_client.get_producer(instance_id, topic_name)

# Send four messages
msg_count = 4
print("%sPublish Message To %s\nTopicName:%s\nMessageCount:%s\n" % (10 * "=", 10 * "=", topic_name, msg_count))

try:
    for i in range(msg_count):
        msg = TopicMessage(
            "I am test message %s.hello" % i,  # Message content
            "tag1"                               # Message tag
        )
        # Set a custom message attribute
        msg.put_property("a", "i")
        # Set the message key for tracing
        msg.set_message_key("MessageKey")

        # Deliver this message after a 10-second delay.
        # The value is a Unix timestamp in milliseconds.
        # For a scheduled message, replace the calculation below
        # with the target delivery time in milliseconds.
        msg.set_start_deliver_time(int(round(time.time() * 1000)) + 10 * 1000)

        re_msg = producer.publish_message(msg)
        print("Publish Timer Message Succeed. MessageID:%s, BodyMD5:%s" % (re_msg.message_id, re_msg.message_body_md5))
except MQExceptionBase as e:
    if e.type == "TopicNotExist":
        print("Topic not exist, please create it.")
        sys.exit(1)
    print("Publish Message Fail. Exception:%s" % e)

**Parâmetro principal: set_start_deliver_time**

Controla quando o broker entrega a mensagem. Passe um timestamp Unix em milissegundos:

Tipo de entrega

Como definir o timestamp

Exemplo

Entrega atrasada

Hora atual mais a duração do atraso

int(round(time.time() * 1000)) + 10 * 1000

Entrega agendada

Timestamp absoluto do horário de entrega alvo

1700000000000

Receber mensagens agendadas e atrasadas

O broker retém mensagens agendadas e atrasadas até o horário de entrega e as disponibiliza para consumo. Consuma-as como mensagens normais.

O exemplo a seguir usa long polling para receber e confirmar mensagens. Substitua os espaços reservados abaixo pelos valores reais:

Espaço reservado

Descrição

Exemplo

<http-endpoint>

Endpoint HTTP da instância

http://xxxxx.mqrest.cn-hangzhou.aliyuncs.com

<topic>

Nome do tópico de origem do consumo

scheduled-msg-topic

<group-id>

ID do grupo de consumidores

GID_scheduled_msg

<instance-id>

ID da instância. Passe uma string vazia se a instância não tiver namespace

MQ_INST_xxxxx

import os
import time

from mq_http_sdk.mq_exception import MQExceptionBase
from mq_http_sdk.mq_consumer import *
from mq_http_sdk.mq_client import *

# Initialize the consumer client
mq_client = MQClient(
    "<http-endpoint>",
    os.environ['ALIBABA_CLOUD_ACCESS_KEY_ID'],
    os.environ['ALIBABA_CLOUD_ACCESS_KEY_SECRET']
)

topic_name = "<topic>"
group_id = "<group-id>"
instance_id = "<instance-id>"

consumer = mq_client.get_consumer(instance_id, topic_name, group_id)

# Long polling timeout in seconds (max: 30)
wait_seconds = 3
# Maximum messages per request (max: 16)
batch = 3

print(("%sConsume And Ak Message From Topic%s\nTopicName:%s\nMQConsumer:%s\nWaitSeconds:%s\n" \
        % (10 * "=", 10 * "=", topic_name, group_id, wait_seconds)))

while True:
    try:
        # Long polling: the request blocks on the broker until a message
        # arrives or wait_seconds elapses, whichever comes first.
        recv_msgs = consumer.consume_message(batch, wait_seconds)
        for msg in recv_msgs:
            print(("Receive, MessageId: %s\nMessageBodyMD5: %s \
                              \nMessageTag: %s\nConsumedTimes: %s \
                              \nPublishTime: %s\nBody: %s \
                              \nNextConsumeTime: %s \
                              \nReceiptHandle: %s \
                              \nProperties: %s\n" % \
                  (msg.message_id, msg.message_body_md5,
                   msg.message_tag, msg.consumed_times,
                   msg.publish_time, msg.message_body,
                   msg.next_consume_time, msg.receipt_handle, msg.properties)))
    except MQExceptionBase as e:
        if e.type == "MessageNotExist":
            print(("No new message! RequestId: %s" % e.req_id))
            continue

        print(("Consume Message Fail! Exception:%s\n" % e))
        time.sleep(2)
        continue

    # Acknowledge consumed messages.
    # If the broker does not receive an ACK before msg.next_consume_time,
    # it redelivers the message. Each delivery generates a new receipt handle.
    try:
        receipt_handle_list = [msg.receipt_handle for msg in recv_msgs]
        consumer.ack_message(receipt_handle_list)
        print(("Ak %s Message Succeed.\n\n" % len(receipt_handle_list)))
    except MQExceptionBase as e:
        print(("\nAk Message Fail! Exception:%s" % e))
        if e.sub_errors:
            for sub_error in e.sub_errors:
                print(("\tErrorHandle:%s,ErrorCode:%s,ErrorMsg:%s" % \
                      (sub_error["ReceiptHandle"], sub_error["ErrorCode"], sub_error["ErrorMessage"])))

Funcionamento do long polling

consume_message bloqueia a solicitação no broker por até wait_seconds. Se uma mensagem ficar disponível nesse período, o broker responde imediatamente. Caso contrário, a solicitação retorna após o tempo limite.

Parâmetro

Descrição

Intervalo

wait_seconds

Tempo limite do long polling em segundos

Máximo: 30

batch

Quantidade máxima de mensagens retornadas por solicitação

Máximo: 16

Funcionamento da confirmação de mensagens

Após processar uma mensagem, confirme-a enviando o receipt handle de volta ao broker. Se nenhum ACK chegar antes de next_consume_time, o broker reentrega a mensagem com um novo receipt handle. Sempre use o handle da entrega mais recente.

Próximos passos