Todos os produtos
Search
Central de documentação

ApsaraMQ for RocketMQ:Message retry

Última atualização: Jun 27, 2026

Quando um consumidor falha ao processar uma mensagem ou o processamento atinge o tempo limite, o ApsaraMQ for RocketMQ reenvia a mensagem automaticamente com base em uma política de nova tentativa. Após o esgotamento de todas as tentativas, a mensagem é movida para uma fila de mensagens mortas. Consuma mensagens nessas filas para restaurar suas operações de negócio.

Observações de uso

  • O ID da mensagem permanece inalterado durante todas as tentativas.

  • A nova tentativa de consumo funciona apenas no modo de consumo por cluster. No modo de consumo por broadcast, as mensagens com falha não são reenviadas; o consumidor avança para a próxima mensagem.

Como funciona

Uma mensagem passa pelos seguintes estados:

Estado

Descrição

Ready

A mensagem está na fila do broker e disponível para consumo.

Inflight

Um consumidor puxou a mensagem e a está processando. Ainda não há resultado retornado.

WaitingRetry

O consumo falhou ou atingiu o tempo limite. A mensagem aguarda o intervalo de nova tentativa antes de retornar ao estado Ready.

Commit

O consumidor retornou uma resposta de sucesso. O consumo foi concluído.

DLQ

Se o recurso de retenção de mensagens mortas estiver ativado, a mensagem será movida para o tópico de mensagens mortas após o esgotamento de todas as tentativas.

TCP message state diagram

Tempo de nova tentativa

O intervalo entre duas tentativas consecutivas de consumo possui três componentes:

Intervalo entre tentativas = duração do consumo + intervalo de nova tentativa + tempo no estado Ready

Retry interval timing diagram

Por exemplo, suponha que uma mensagem aguarde 5 segundos no estado Ready e leve 6 segundos para ser processada antes de falhar. Com um intervalo de nova tentativa de 10 segundos:

  1. 0 s — A mensagem entra no estado Ready.

  2. 5 s — O consumidor puxa a mensagem (Inflight).

  3. 11 s — O consumo falha após 6 segundos. A mensagem entra em WaitingRetry.

  4. 21 s — Após o intervalo de nova tentativa de 10 segundos, a mensagem retorna ao estado Ready.

  5. 26 s — O consumidor puxa a mensagem novamente para a próxima tentativa.

Intervalo total: 6 + 10 + 5 = 21 segundos.

Políticas de nova tentativa para TCP

Mensagens ordenadas

Configuração

Detalhes

Intervalo de nova tentativa

Definido pelo parâmetro suspendTimeMillis. Faixa válida: 10 a 30.000 ms. Padrão: 1.000 ms (1 segundo).

Máximo de novas tentativas

Definido pelo parâmetro MaxReconsumeTimes. Sem limite superior. Padrão: Integer.MAX.

Mensagens não ordenadas

Configuração

Detalhes

Intervalo de nova tentativa

Segue um cronograma escalonado predefinido (consulte a tabela abaixo). Intervalos personalizados não são suportados para mensagens não ordenadas.

Máximo de novas tentativas

Definido pelo parâmetro MaxReconsumeTimes. Sem limite superior. Padrão: 16.

Se MaxReconsumeTimes exceder 16, o cronograma predefinido se aplica às primeiras 16 tentativas. Todas as tentativas subsequentes usam um intervalo fixo de 2 horas.

Cronograma de intervalo de nova tentativa para mensagens não ordenadas

Tentativa

Intervalo

Tentativa

Intervalo

1

10 segundos

9

7 minutos

2

30 segundos

10

8 minutos

3

1 minuto

11

9 minutos

4

2 minutos

12

10 minutos

5

3 minutos

13

20 minutos

6

4 minutos

14

30 minutos

7

5 minutos

15

1 hora

8

6 minutos

16

2 horas

Políticas de nova tentativa para HTTP

As políticas de nova tentativa HTTP são predefinidas e não podem ser modificadas.

Tipo de mensagem

Intervalo de nova tentativa

Máximo de novas tentativas

Ordenada

1 minuto

288

Não ordenada

5 minutos

288

Configure comportamento de nova tentativa para TCP

Ative nova tentativa

Para acionar uma nova tentativa quando o consumo falhar no modo de consumo por cluster, implemente a interface MessageListener com uma das seguintes abordagens:

  • **Retornar Action.ReconsumeLater** (recomendado)

  • Retornar null

  • Lançar uma exceção

public class MessageListenerImpl implements MessageListener {

    @Override
    public Action consume(Message message, ConsumeContext context) {
        // If the consumption logic throws an exception, the message is retried.
        doConsumeMessage(message);
        // Method 1: Return Action.ReconsumeLater and retry the message.
        return Action.ReconsumeLater;
        // Method 2: Return null and retry the message.
        return null;
        // Method 3: Throw an exception and retry the message.
        throw new RuntimeException("Consumer Message exception");
    }
}

Desativar nova tentativa

Para evitar o reenvio, capture todas as exceções na lógica de consumo e retorne Action.CommitMessage:

public class MessageListenerImpl implements MessageListener {

    @Override
    public Action consume(Message message, ConsumeContext context) {
        try {
            doConsumeMessage(message);
        } catch (Throwable e) {
            // Catch all exceptions and return CommitMessage to skip retry.
            return Action.CommitMessage;
        }
        // Consumption succeeded.
        return Action.CommitMessage;
    }
}

Personalizar o intervalo de nova tentativa e o máximo de tentativas

Nota

A configuração personalizada de nova tentativa requer o SDK de cliente TCP para Java versão 1.2.2 ou posterior. Para mais informações, consulte Notas de versão.

Defina MaxReconsumeTimes e SuspendTimeMillis nas propriedades do consumidor antes de iniciá-lo. Os intervalos personalizados de nova tentativa aplicam-se apenas a mensagens ordenadas. Mensagens não ordenadas sempre seguem o cronograma predefinido.

Properties properties = new Properties();
// Set the maximum number of retries to 20.
properties.put(PropertyKeyConst.MaxReconsumeTimes, "20");
// Set the retry interval to 3,000 milliseconds (ordered messages only).
properties.put(PropertyKeyConst.SuspendTimeMillis, "3000");
Consumer consumer = ONSFactory.createConsumer(properties);
Importante

Todos os consumidores no mesmo grupo de consumidores compartilham a configuração de nova tentativa. O consumidor iniciado mais recentemente substitui a configuração dos consumidores anteriores. Certifique-se de que todos os consumidores em um grupo usem valores idênticos para MaxReconsumeTimes e SuspendTimeMillis.

Consultar a contagem de novas tentativas

Após receber uma mensagem, chame message.getReconsumeTimes() para verificar quantas vezes ela foi submetida a nova tentativa:

public class MessageListenerImpl implements MessageListener {

    @Override
    public Action consume(Message message, ConsumeContext context) {
        // Get the current retry count.
        System.out.println(message.getReconsumeTimes());
        return Action.CommitMessage;
    }
}

Melhores práticas

  • Comece com os valores padrão de nova tentativa. O cronograma padrão para mensagens não ordenadas (escalando de 10 segundos a 2 horas em 16 tentativas) funciona bem para a maioria das falhas transitórias. Faça ajustes somente após observar os padrões reais de falha do seu sistema.

  • Configure o monitoramento da fila de mensagens mortas. As mensagens que esgotam todas as tentativas são movidas para essa fila. Monitore-a e configure alertas para investigar e reprocessar rapidamente as mensagens com falha.

  • Mantenha a lógica de consumo idempotente. Como as mensagens podem ser entregues mais de uma vez durante as novas tentativas, projete seu consumidor para lidar com segurança com o processamento duplicado.

  • Evite consumos de longa duração. Se o processamento demorar muito, a mensagem pode atingir o tempo limite e acionar uma nova tentativa desnecessária. Divida tarefas longas em etapas menores ou aumente o tempo limite de consumo.

Próximos passos