Lorsqu'un consommateur échoue à traiter un message ou que le traitement expire, ApsaraMQ for RocketMQ redistribue automatiquement le message selon une politique de nouvelle tentative. Une fois toutes les tentatives épuisées, le message est déplacé vers une file de messages non livrables. Vous pouvez consommer les messages présents dans les files de messages non livrables pour rétablir votre activité.
Remarques d'utilisation
L'ID du message reste inchangé lors de toutes les tentatives de redistribution.
La nouvelle tentative de consommation fonctionne uniquement en mode de consommation en cluster. En mode de consommation par diffusion, les messages ayant échoué ne sont pas redistribués : le consommateur passe au message suivant.
Fonctionnement
Un message traverse les états suivants :
| État | Description |
|---|---|
| Ready | Le message est mis en file d'attente dans le broker et disponible pour la consommation. |
| Inflight | Un consommateur a extrait le message et le traite. Aucun résultat n'a encore été renvoyé. |
| WaitingRetry | La consommation a échoué ou a expiré. Le message attend la fin de l'intervalle de nouvelle tentative avant de revenir à l'état Ready. |
| Commit | Le consommateur a renvoyé une réponse de succès. La consommation est terminée. |
| DLQ | Si la fonctionnalité de conservation des messages non livrables est activée, le message est déplacé vers la rubrique de messages non livrables après épuisement de toutes les tentatives. |

Chronologie des nouvelles tentatives
L'intervalle entre deux tentatives de consommation consécutives comprend trois composantes :
Intervalle entre les tentatives = durée de consommation + intervalle de nouvelle tentative + temps passé dans l'état Ready

Par exemple, supposons qu'un message attende 5 secondes dans l'état Ready et prenne 6 secondes pour être traité avant d'échouer. Avec un intervalle de nouvelle tentative de 10 secondes :
0 s : Le message passe à l'état Ready.
5 s : Le consommateur extrait le message (Inflight).
11 s : La consommation échoue après 6 secondes. Le message passe à l'état WaitingRetry.
21 s : Après l'intervalle de nouvelle tentative de 10 secondes, le message revient à l'état Ready.
26 s : Le consommateur extrait à nouveau le message pour la tentative suivante.
Intervalle total : 6 + 10 + 5 = 21 secondes.
Politiques de nouvelle tentative pour TCP
Messages ordonnés
| Paramètre | Détails |
|---|---|
| Intervalle de nouvelle tentative | Défini avec le paramètre suspendTimeMillis. Plage valide : 10 à 30 000 ms. Valeur par défaut : 1 000 ms (1 seconde). |
| Nombre maximal de tentatives | Défini avec le paramètre MaxReconsumeTimes. Aucune limite supérieure. Valeur par défaut : Integer.MAX. |
Messages non ordonnés
| Paramètre | Détails |
|---|---|
| Intervalle de nouvelle tentative | Suit un planning prédéfini croissant (voir le tableau ci-dessous). Les intervalles personnalisés ne sont pas pris en charge pour les messages non ordonnés. |
| Nombre maximal de tentatives | Défini avec le paramètre MaxReconsumeTimes. Aucune limite supérieure. Valeur par défaut : 16. |
Si MaxReconsumeTimes dépasse 16, le planning prédéfini s'applique aux 16 premières tentatives. Toutes les tentatives suivantes utilisent un intervalle fixe de 2 heures.
Planning des intervalles de nouvelle tentative pour les messages non ordonnés
| Nouvelle tentative | Intervalle | Nouvelle tentative | Intervalle |
|---|---|---|---|
| 1 | 10 secondes | 9 | 7 minutes |
| 2 | 30 secondes | 10 | 8 minutes |
| 3 | 1 minute | 11 | 9 minutes |
| 4 | 2 minutes | 12 | 10 minutes |
| 5 | 3 minutes | 13 | 20 minutes |
| 6 | 4 minutes | 14 | 30 minutes |
| 7 | 5 minutes | 15 | 1 heure |
| 8 | 6 minutes | 16 | 2 heures |
Politiques de nouvelle tentative pour HTTP
Les politiques de nouvelle tentative HTTP sont prédéfinies et ne peuvent pas être modifiées.
| Type de message | Intervalle de nouvelle tentative | Nombre maximal de tentatives |
|---|---|---|
| Ordonné | 1 minute | 288 |
| Non ordonné | 5 minutes | 288 |
Configurer le comportement de nouvelle tentative pour TCP
Activer la nouvelle tentative
Pour déclencher une nouvelle tentative en cas d'échec de la consommation en mode de consommation en cluster, implémentez l'interface MessageListener en utilisant l'une des approches suivantes :
**Renvoyer
Action.ReconsumeLater** (recommandé)Renvoyer
nullLever une exception
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");
}
}
Désactiver la nouvelle tentative
Pour empêcher la redistribution, interceptez toutes les exceptions dans votre logique de consommation et renvoyez 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;
}
}
Personnaliser l'intervalle de nouvelle tentative et le nombre maximal de tentatives
La configuration personnalisée des nouvelles tentatives nécessite la version 1.2.2 ou ultérieure du SDK client TCP pour Java. Pour plus d'informations, consultez les Notes de version.
Définissez MaxReconsumeTimes et SuspendTimeMillis dans les propriétés du consommateur avant de démarrer ce dernier. Les intervalles de nouvelle tentative personnalisés s'appliquent uniquement aux messages ordonnés. Les messages non ordonnés suivent toujours le planning prédéfini.
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);
Tous les consommateurs d'un même groupe de consommateurs partagent la configuration de nouvelle tentative. Le consommateur démarré le plus récemment écrase la configuration des consommateurs précédents. Assurez-vous que tous les consommateurs d'un groupe utilisent des valeurs identiques pour MaxReconsumeTimes et SuspendTimeMillis.
Consulter le nombre de nouvelles tentatives
Une fois qu'un consommateur a reçu un message, appelez message.getReconsumeTimes() pour vérifier le nombre de fois où le message a fait l'objet d'une nouvelle tentative :
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;
}
}
Bonnes pratiques
Commencez par les valeurs par défaut. Le planning par défaut pour les messages non ordonnés (croissant de 10 secondes à 2 heures sur 16 tentatives) convient à la plupart des pannes transitoires. Ajustez les paramètres uniquement après avoir observé les schémas d'échec réels de votre système.
Configurez la surveillance des files de messages non livrables. Les messages ayant épuisé toutes les tentatives sont déplacés vers une file de messages non livrables. Surveillez cette file et configurez des alertes afin de pouvoir enquêter et retraiter rapidement les messages ayant échoué.
Maintenez l'idempotence de la logique de consommation. Étant donné que les messages peuvent être distribués plusieurs fois lors des nouvelles tentatives, concevez votre consommateur de manière à gérer en toute sécurité les traitements en double.
Évitez les consommations de longue durée. Si le traitement prend trop de temps, le message peut expirer et déclencher une nouvelle tentative inutile. Décomposez les tâches longues en étapes plus petites ou augmentez le délai d'expiration de la consommation.
Étapes suivantes
Files de messages non livrables : Gérez les messages qui échouent après toutes les tentatives de nouvelle tentative.
Notes de version : Vérifiez les exigences de version du SDK client TCP.