Informations générales
Qu'est-ce qu'une relation d'abonnement cohérente ?
Un abonnement cohérent est une règle selon laquelle tous les consommateurs d'un même groupe doivent s'abonner exactement au même ensemble de topics et de tags. Bien qu'un consommateur puisse s'abonner à plusieurs topics, cet ensemble d'abonnements doit être identique pour tous les autres consommateurs du groupe. Cela garantit une distribution prévisible des messages et empêche leur perte.
Pour plus d'informations, reportez-vous à la rubrique Relations d'abonnement cohérentes.
Comment les consommateurs s'abonnent à plusieurs topics et tags
Commercial Java SDK
Exemple de coordonnées Maven :
<groupId>com.aliyun.openservices</groupId>
<artifactId>ons-client</artifactId>
<version>x.x.x.Final</version>
Exemple de code :
Properties properties = new Properties();
// The Group ID that you created in the ApsaraMQ for RocketMQ console.
properties.setProperty(PropertyKeyConst.GROUP_ID, "GID-xxxxx");
/*
* Some property configurations
*/
Consumer consumer = ONSFactory.createConsumer(properties);
// Subscribe to multiple tags.
consumer.subscribe("TopicTestMQ1", "TagA||TagB", new MessageListener() {...});
// Subscribe to multiple topics. Call subscribe again on the same consumer instance to add subscriptions.
consumer.subscribe("TopicTestMQ2", "TagA||TagB", new MessageListener() {...});
Community Java SDK (artifactId: rocketmq-client)
Exemple de coordonnées Maven :
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client</artifactId>
<version>x.x.x</version>
Exemple de code :
// The Group ID that you created in the ApsaraMQ for RocketMQ console.
DefaultMQPushConsumer consumer = new DefaultMQPushConsumer(GROUP_ID, getAclRPCHook(), new AllocateMessageQueueAveragely(), true, null);
/*
* Some property configurations
*/
// Subscribe to multiple tags
consumer.subscribe("java-test", "TagA||TagB");
// Subscribe to a second topic. Note that a consumer can register only one consumption logic. This means the same logic applies to all subscriptions.
consumer.subscribe("cxtest", "*");
consumer.registerMessageListener(new MessageListenerConcurrently() {...});
Community Java SDK (artifactId: rocketmq-client-java)
Exemple de coordonnées Maven :
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-client-java</artifactId>
<version>5.0.8</version>
Exemple de code :
final ClientServiceProvider provider = ClientServiceProvider.loadService();
/*
* Some configurations
*/
HashMap<String, FilterExpression> sub = new HashMap<>();
// Subscribe to multiple tags
sub.put("Topic1", new FilterExpression("TagA||TagB", FilterExpressionType.TAG));
// Subscribe to a second topic. Note that a consumer can register only one consumption logic. This means the same logic applies to all subscriptions.
sub.put("Topic2", new FilterExpression("TagA||TagB", FilterExpressionType.TAG));
PushConsumer pushConsumer = provider.newPushConsumerBuilder()
.setClientConfiguration(clientConfiguration)
// Set the consumer group. Use the Group ID created in the ApsaraMQ for RocketMQ console.
.setConsumerGroup(consumerGroup)
// Set the pre-attached subscription relationships.
.setSubscriptionExpressions(sub)
// Set the message listener.
.setMessageListener(messageView -> {...})
.build();
SpringBoot framework (using the RocketMQMessageListener annotation)
Si vous utilisez l'annotation RocketMQMessageListener pour démarrer un consommateur, sachez que chaque annotation lance une instance de consommateur distincte. Si votre code utilise plusieurs annotations, chacune s'abonnant à un topic différent, cela entraîne une incohérence dans la relation d'abonnement.
Par exemple, le code suivant implémente l'interface RocketMQListener deux fois, ce qui permet de s'abonner à TopicA et TopicB au sein du même groupe. À l'exécution, le client crée deux instances de consommateur. Il en résulte que deux consommateurs du même groupe sont abonnés respectivement à TopicA et TopicB, ce qui provoque une incohérence de la relation d'abonnement.
// Business logic 1: TestMessageListener1.java
@Component
@RocketMQMessageListener(consumerGroup="GID_A", topic = "TopicA")
public class TestMessageListener1 implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt messageExt) {
/*
* Some configurations
*/
}
}
// Business logic 2: TestMessageListener2.java
@Component
@RocketMQMessageListener(consumerGroup="GID_A", topic = "TopicB")
public class TestMessageListener2 implements RocketMQListener<MessageExt> {
@Override
public void onMessage(MessageExt messageExt) {
/*
* Some configurations
*/
}
}
Pour gérer plusieurs abonnements, redéfinissez la méthode prepareStart de l'interface RocketMQPushConsumerLifecycleListener. L'exemple de code ci-dessous illustre cette approche :
@Component
@RocketMQMessageListener(consumerGroup = "GID_A", topic = "")
public class TestMessageListener implements RocketMQListener<MessageExt>, RocketMQPushConsumerLifecycleListener {
@Override
public void onMessage(MessageExt messageExt) {}
@Override
public void prepareStart(DefaultMQPushConsumer defaultMQPushConsumer) {
try{
// Subscribe to multiple tags
defaultMQPushConsumer.subscribe("TopicA", "TagA||TagB");
// Subscribe to a second topic
defaultMQPushConsumer.subscribe("TopicB", "*");
// Register the consumption logic
defaultMQPushConsumer.registerMessageListener((List<MessageExt> messages, ConsumeConcurrentlyContext context) -> {......});
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
SpringBoot framework (using the Bean annotation)
Cette méthode injecte manuellement un ConsumerBean. Vous devez utiliser la méthode native du SDK pour créer plusieurs abonnements.
@Configuration
public class ConsumerClient {
@Bean(initMethod = "start", destroyMethod = "shutdown")
public ConsumerBean buildConsumer() {
// Inject the corresponding ConsumerBean here. Refer to the multiple subscription methods for the commercial and community SDKs.
}
}
Description du scénario
La console ApsaraMQ for RocketMQ indique que la relation d'abonnement est incohérente.
Étapes rapides de dépannage
Dans la console, localisez l'instance RocketMQ correspondante.
Sur la page des détails du groupe, consultez la distribution des clients pour le groupe présentant une relation d'abonnement incohérente.
Selon le SDK ou le framework utilisé, corrigez la relation d'abonnement afin de garantir sa cohérence.
Détails du dépannage
Commencez par vérifier si vous utilisez une instance de version 5.0 ou 4.0. La console affiche les relations d'abonnement différemment selon la version.
RocketMQ 5.0 instances
Accédez à la page des détails du groupe pour afficher la liste des clients et leurs Subscriptions associées.
Les relations d'abonnement sont affichées par topic. La colonne Filter Expression affiche toutes les expressions utilisées par les consommateurs du groupe pour s'abonner au topic correspondant.
-
Pour identifier rapidement les consommateurs dont la relation d'abonnement est incohérente, cliquez sur View Distribution afin d'obtenir des informations détaillées sur l'abonnement de chaque consommateur. Concentrez-vous ensuite sur la colonne Host IP/Public IP. En général,
<IP>:<Port>identifie de manière unique une instance de consommateur, c'est-à-dire l'entité d'exécution créée lors de l'initialisation de la classe Consumer. Vous pouvez analyser la situation de plusieurs façons :Si la page n'affiche qu'un seul topic comportant plusieurs entrées Filter Expression, cela signifie que différents consommateurs ont défini des tags distincts pour ce topic. Dans ce cas, cliquez sur View Distribution à droite pour consulter l'état d'abonnement de tous les consommateurs pour ce topic. Modifiez votre code métier si nécessaire afin que tous les consommateurs s'abonnent aux mêmes tags.
Si la page affiche plusieurs topics et que chacun ne possède qu'une seule entrée Filter Expression, cela indique que certains consommateurs sont abonnés à plusieurs topics. Dans ce cas, cliquez sur View Distribution pour chaque topic. Organisez les informations d'abonnement de chaque consommateur en fonction de la dimension Host IP/Public IP.
Si la page affiche plusieurs topics et que chaque topic comporte plusieurs entrées Filter Expression, cliquez sur View Distribution pour réorganiser les relations d'abonnement des consommateurs selon la dimension Host IP/Public IP. Cette opération vous aide à comprendre rapidement les relations d'abonnement du point de vue du consommateur.
RocketMQ 4.0 instances
Accédez à la page des détails du groupe. La zone Subscriptions affiche les informations d'abonnement du groupe par client.