このトピックでは、メッセージ配信の失敗、消費エラー、メッセージバックログなど、ApsaraMQ for RabbitMQ の問題をトラブルシューティングするのに役立つ、Simple Log Service (SLS) の一般的なクエリについて説明します。
前提条件
一般的なクエリ
このトピックでは、一般的な Simple Log Service (SLS) クエリを一覧で紹介します。 詳細な手順とログ形式の説明については、「ログ管理」をご参照ください。
エクスチェンジによるプロデューサー IP アドレスの検索
次のクエリを実行して、プロデューサーの IP アドレスを一覧で表示します。
* and Action : SendMessage and Code : 200 |
select
split_part(ResourceName,',',2) as exchange_name,
split_part(ResourceName, ',', 3) as routing_key,
RemoteAddress as ip_port,
count(*) as total_send_num
group by
exchange_name, routing_key, ip_port
order by
total_send_num DESC
limit 1000000
キューによるコンシューマー IP アドレスの検索
次のクエリを実行して、コンシューマーの IP アドレスを一覧で表示します。
* and Action : PushMessage and Code : 200 |
select
InstanceId as instance_id,
VHost as virtual_host,
Queue as queue_name,
RemoteAddress as ip_port,
count(*) as push_total_num
group by
instance_id,virtual_host, ip_port, queue_name
order by
push_total_num DESC
limit 10000000
メッセージのトレース
検索ボックスでクエリを実行して、メッセージをトレースします。
-
メッセージ ID によるメッセージのトレース
InstanceId:amqp-cn-i7m29o3s**** and VHost:cycle**** and ResourceName:msgId=27127757-44dc-4373-afc5-f8ea12f****クエリを実行すると、2 つのログエントリが返されます。1 つは Action が
SendMessage(Code: 200) で、もう 1 つは Action がPushMessage(Code: 200) です。 これは、メッセージが正常に送信およびプッシュされたことを示します。クライアントが
BasicConsumeを使用してサブスクライブすると、メッセージを送信からサーバー配信までトレースできます。SendMessageアクションはクライアントのBasicPublish呼び出しに対応し、PushMessageアクションはサーバーがクライアントにメッセージをプッシュすることに対応します。 クライアントがBasicGetを使用してメッセージをプルする場合、Action はPushMessageの代わりにBasicGetになります。説明-
ログ結果に
SendMessageエントリが 1 つだけ含まれ、PushMessage or BasicGetエントリが複数含まれている場合、クライアントは最初のPushMessage or BasicGetの後、consumption timeout内にBasicAckを呼び出してメッセージの確認応答に失敗した可能性があります。これにより、サーバーは消費が失敗したと見なし、メッセージを再配信します。consumption timeout の詳細については、「インスタンスの再試行ポリシーのパラメーターの説明」をご参照ください。 -
ログ結果に
SendMessageおよびPushMessageに加えてSendDlqMessageログが含まれている場合、SendDlqMessageログは現在のメッセージがデッドレターキューに移動されたことを示します。
-
-
メッセージが消費されたかどうかの確認
InstanceId:amqp-cn-i7m29o3s**** and VHost:cycle**** and Queue:cycleCheckQueue**** and ConnectionId:00163efffe08281f-00004e11-0009732f-799c0af9bc4e4913-96b3**** and ChannelId:1 and (ResourceName:deliveryTag=90 or Property:deliveryTag=90) and RemoteAddress:"/192.168.XX.XX:XXXX"PushMessageログから ConnectionId、ChannelId、deliveryTag、および RemoteAddress の値を取得します。RemoteAddress はクライアントの IP アドレスです。ConnectionId は接続の一意の識別子です。ChannelId はチャネルの一意の識別子です。deliveryTagはメッセージに対するサーバーの一意の識別子です。DeleteMessageログエントリは、メッセージがクライアントによって正常に消費されたことを示します。クエリを実行すると、通常は
PushMessage、BasicAck、DeleteMessageのアクションに対応する 3 つのログエントリが返されます。このうち、Action がDeleteMessageとBasicAckであり、それぞれの Code が200であるログエントリは、メッセージが正常に消費されたことを示します。説明クライアントが
autoAck=falseを設定してBasicConsumeを呼び出す場合、クライアントはBasicAckを呼び出して、メッセージが消費されたことを確認する必要があります。その後、サーバーはメッセージを削除します。BasicAckの呼び出しは、PushMessageタイムスタンプから開始される消費タイムアウト期間内に行う必要があります。タイムアウト期間を超えた場合、サーバーは消費が失敗したとみなし、メッセージをクライアントに再配信します。詳細については、「インスタンスの再試行ポリシーパラメーターの説明」をご参照ください。-
クライアントが
BasicAckを呼び出しても、メッセージ消費ステータスのクエリでDeleteMessageログエントリが返されない場合は、消費に失敗しています。PushMessageエントリとBasicAckエントリの時間差を確認してください。その差が消費タイムアウトを超えている場合、BasicAckの呼び出しは無効です。 -
PushMessageとDeleteMessageのエントリのみが見つかり、BasicAckエントリが見つからない場合、クライアントはBasicAck(deliveryTag, multiple=true)を使用して、指定されたdeliveryTagまでのすべての以前のメッセージを 1 回の呼び出しで確認応答した可能性があります。
-
キュー消費率の分析
次のクエリを実行して、SendMessage、PushMessage or BasicGet、BasicAck、および DeleteMessage アクションの分布を確認します。 これら 4 つのアクションの割合がほぼ等しい場合、生産レートと消費レートのバランスが取れており、メッセージの滞留はほとんどありません。
InstanceId:amqp-cn-i7m29o3s**** and Vhost:cycle**** and Queue: cycleCheckQueue**** and (SendMessage or PushMessage or BasicAck or DeleteMessage)
クエリ結果ページの左側にある [クイック分析] パネルで、Action フィールドの分布を表示します。 たとえば、分布は BasicAck 25%、DeleteMessage 25%、PushMessage 25%、SendMessage 24% のようになります。
ログに次のいずれかのパターンが見られる場合は、考えられる原因を分析してください。
-
ログ結果に
DeleteMessageエントリがないのは、クライアントがautoAck=trueをBasicConsumeまたはBasicGetの呼び出し時に設定したことが原因である可能性があります。あるいは、クライアントからのすべてのBasicAckリクエストが消費タイムアウトを超過し、呼び出しが無効になった可能性もあります。消費タイムアウトの詳細については、「インスタンスの再試行ポリシーパラメーターの説明」をご参照ください。 -
PushMessageエントリの割合がSendMessageエントリの割合よりもはるかに低い場合、サブスクライバーが不足している可能性があります。接続を追加し、新しいコンシューマーを作成することをお勧めします。 -
SendMessageとPushMessageエントリの割合は同様ですが、DeleteMessageエントリの割合は大幅に低くなっています。これは、多くのBasicAckリクエストが消費タイムアウトを超えて無効になったためと考えられます。消費タイムアウトの詳細については、「インスタンスの再試行ポリシーパラメーターの説明」をご参照ください。 -
SendMessage、PushMessage、およびDeleteMessageの割合はほぼ同じですが、BasicAckの割合がはるかに低い場合は、コードでBasicAck(multiple=true)を使用しているかどうかを確認してください。
デッドレターメッセージのクエリ
ログ検索ボックスにクエリを入力して、関連するメッセージを取得します。
-
メッセージの TTL 切れによりデッドレターキューにルーティングされたメッセージ
InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and ResourceName:msgId=02a162ba-f842-440f-bfd4-2595dd19****クエリを実行すると、2 つのログエントリが返されます。 両方のエントリで
Codeフィールドは 200 であり、メッセージ操作が成功したことを示します。SendMessageエントリは、メッセージを送信するためのBasicPublish呼び出しに対応します。SendDlqMessageエントリは、メッセージの TTL が期限切れになり、対応するデッドレターキューに送信されたことを示します。説明このログエントリは、デッドレターキューを設定している場合にのみ生成されます。
-
キューの TTL 切れによりデッドレターキューにルーティングされたメッセージ
-
キューにデッドレタープロパティと TTL を設定します。
Map<String, Object> argument = new HashMap<>(); argument.put("x-dead-letter-exchange", [exchangeName]); argument.put("x-dead-letter-routing-key", [routingKey]); argument.put("x-message-ttl", [ttl]); channel.queueDeclare([queueName], true, false, false, argument); -
ログ検索ボックスに次のクエリを入力すると、
SendMessageおよびSendDlqMessageのエントリが取得されます。InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and ResourceName:msgId=034a75c5-d957-422f-822e-72dfad2a****クエリを実行すると、2 つのログエントリが返されます。1 つはキュー a に対する
SendDlqMessageアクション、もう 1 つはキュー b に対するSendMessageアクションです。 Code は両方とも 200 です。 左側の [クイック分析] パネルでは、Action フィールドの分布は SendMessage 50% と SendDlqMessage 50% を示します。
-
-
requeue=falseを指定してBasicRejectまたはBasicNackを呼び出します。InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and (ResourceName:msgId=034a75c5-d957-422f-822e-72dfad2a**** or ResourceName:deliveryTag=1)PushMessageログエントリは、サーバーがクライアントにメッセージをプッシュしたことを示します。 メッセージを受信した後、クライアントはBasicReject(requeue=false)を呼び出します。 対応するSendDlqMessageログエントリは、メッセージがデッドレターキューにルーティングされたことを示します。
クエリを実行すると、PushMessage (Code: 200)、BasicReject (Code: 200)、SendDlqMessage (Code: 200) のアクションを含む 3 つのログエントリが返されます。