一貫性のあるサブスクリプション関係
はじめに
サブスクリプション関係は、RocketMQドメインモデルの非常に重要な部分であり、コンシューマーによるメッセージ消費の制御メタデータを表現するために使用されます。完全な概念については、サブスクリプション関係モデルを参照してください。
同じコンシューマーグループ内のすべてのコンシューマーインスタンスが、トピックとタグに対してまったく同じサブスクリプションを持っている場合、サブスクリプション関係は一貫性があります。サブスクリプション関係(コンシューマーグループ名 - トピック - タグ)が一貫していない場合、メッセージの消費に混乱が生じ、メッセージの損失につながる可能性があります。
1 正しいサブスクリプション関係の例
1.1 サブスクライブされているトピックが同じで、フィルター式が一貫している
次の図に示すように、同じConsumerGroup内の3つのConsumerインスタンスC1、C2、およびC3はすべてTopicAをサブスクライブしており、TopicAのTagへのサブスクリプションはすべてTag1であり、サブスクリプション関係の一貫性の原則を満たしています。
正しいコード例 1
C1、C2、およびC3のサブスクリプション関係は一貫性があります。つまり、C1、C2、およびC3のメッセージをサブスクライブするためのコードはまったく同じでなければならず、コード例は次のとおりです。
PushConsumer consumer1 = provider.newPushConsumerBuilder().setConsumerGroup("GroupA").build();
consumer1.subscribe("TopicA", new FilterExpression("TagA", FilterExpressionType.TAG));
PushConsumer consumer2 = provider.newPushConsumerBuilder().setConsumerGroup("GroupA").build();
consumer2.subscribe("TopicA", new FilterExpression("TagA", FilterExpressionType.TAG));
PushConsumer consumer3 = provider.newPushConsumerBuilder().setConsumerGroup("GroupA").build();
consumer3.subscribe("TopicA", new FilterExpression("TagA", FilterExpressionType.TAG));
RocketMQはサブスクリプション関係の一貫性を重視しています。これは、サーバーの観点からは、グループ内のすべてのコンシューマーが同じ論理コピーである必要があるため、同じConsumerGroup内のすべてのコンシューマーが一貫している必要があることを意味します。
サブスクリプション関係の一貫性を重視するということは、コンシューマーが複数のトピックをサブスクライブできないという意味ではありません。各コンシューマーは必要に応じて複数のトピックをサブスクライブできますが、前提条件は、同じコンシューマーグループ内のコンシューマーが一貫していることです。
2 一貫性のないサブスクリプション関係のトラブルシューティング
問題の説明
RocketMQバージョンのメッセージキューを使用する場合、サブスクリプション関係が一貫しない可能性があります。具体的な問題は次のとおりです。
- RocketMQバージョンのメッセージキューコンソールでのサブスクリプション関係の一貫性は「いいえ」と表示されます。
- コンシューマーインスタンスは、サブスクライブされたメッセージを受信しません。
確認するには、次の手順を参照してください。
Apache RocketMQコンソールまたはCLiツールで、指定されたグループのサブスクリプション関係が一貫しているかどうかを確認できます。クエリ結果が一貫していない場合は、この記事の一般的なサブスクリプション関係の不一致の問題を参照して、コンシューマーインスタンスの消費コードのトラブルシューティングを行ってください。
- Consumerインスタンスのサブスクリプションに関連する設定コードを確認し、同じConsumerGroup内のすべてのConsumerインスタンスが同じトピックとタグをサブスクライブしていることを確認します。
- コンソールまたはCliコマンドConsumerConnectionを使用して、有効なサブスクリプション関係が一貫しているかどうかを確認します。
- メッセージが予期されたコンシューマーインスタンスによって消費できることをテストして確認します。
3 一貫性のないサブスクリプション関係の一般的な問題
3.1 同じConsumerGroup内で、Consumerインスタンスがサブスクライブしているトピックが異なる(3.x、4.x SDKに適用)
SDKの初期の3.x / 4.xバージョンでは、次の図に示すように、同じConsumerGroup内の3つのConsumerインスタンスC1、C2、およびC3は、それぞれTopicA、TopicB、およびTopicCをサブスクライブしており、サブスクライブされたトピックが一貫しておらず、一貫性のあるサブスクリプションの原則に準拠していません。
5.xバージョンのSDKは、同じConsumerGroup内のConsumerインスタンスが異なるトピックをサブスクライブすることをサポートするようになりました。
3.2 同じConsumerGroup内のConsumerインスタンスが同じトピックをサブスクライブしているが、サブスクライブされているタグが異なる。
次の図に示すように、同じConsumerGroup内のConsumerインスタンスC1、C2、およびC3はすべてTopicAをサブスクライブしていますが、C1はTopicAのTag1をサブスクライブし、C2とC3はTopicAのTag2をサブスクライブしています。同じトピックのサブスクライブされたタグが一貫しておらず、サブスクリプション関係の一貫性の原則に準拠していません。
誤ったコード例 2
コンシューマー例 2-1:
PushConsumer consumer1 = provider.newPushConsumerBuilder().setConsumerGroup("GroupA").build();
consumer1.subscribe("TopicA", new FilterExpression("Tag1", FilterExpressionType.TAG));
コンシューマー例 2-2:
PushConsumer consumer2 = provider.newPushConsumerBuilder().setConsumerGroup("GroupA").build();
consumer2.subscribe("TopicA", new FilterExpression("Tag2", FilterExpressionType.TAG));コンシューマー例 2-3:
PushConsumer consumer3 = provider.newPushConsumerBuilder().setConsumerGroup("GroupA").build();
consumer3.subscribe("TopicA", new FilterExpression("Tag2", FilterExpressionType.TAG));