このトピックでは、ApsaraMQ for RabbitMQ インスタンスで生成されたログを使用して、問題を特定および分析する方法について説明します。メッセージが期待どおりに送受信されない場合、またはメッセージの消費中に例外またはメッセージの蓄積が発生した場合、このトピックで説明されている方法を使用して例外を特定し、ビジネスの安定性を確保できます。
前提条件
メッセージログ管理機能が有効になっており、インデックスが構成されています。詳細については、「メッセージログ管理」をご参照ください。
一般的なステートメントの概要
このトピックでは、Simple Log Service の一般的なクエリステートメントについて説明します。操作とログ形式の詳細については、「メッセージログ管理」をご参照ください。
exchange 別のプロデューサーの IP アドレスのリストをクエリする
Simple Log Service の検索ボックスに、次のステートメントを入力してプロデューサーの IP アドレスのリストをクエリします。
* and Action : SendMessage and Code : 200 |
select
split_part(ResourceName,',',2) as exchange_name, // exchange 名として ResourceName の2番目の部分を抽出
split_part(ResourceName, ',', 3) as routing_key, // routing_key として ResourceName の3番目の部分を抽出
RemoteAddress as ip_port, // ip_port として RemoteAddress を抽出
count(*) as total_send_num // 送信されたメッセージの総数を計算
group by
exchange_name, routing_key, ip_port // exchange_name、routing_key、ip_port でグループ化
order by
total_send_num DESC // total_send_num の降順でソート
limit 1000000 // 結果を最大100万件に制限次の図は、クエリの結果の例を示しています。
queue 別のコンシューマーの IP アドレスのリストをクエリする
Simple Log Service の検索ボックスに、次のステートメントを入力してコンシューマーの IP アドレスのリストをクエリします。
* and Action : PushMessage and Code : 200 |
select
InstanceId as instance_id, // インスタンス ID を抽出
VHost as virtual_host, // 仮想ホストを抽出
Queue as queue_name, // queue 名を抽出
RemoteAddress as ip_port, // ip とポートを抽出
count(*) as push_total_num // push されたメッセージの総数を計算
group by
instance_id,virtual_host, ip_port, queue_name // instance_id、virtual_host、ip_port、queue_name でグループ化
order by
push_total_num DESC // push_total_num の降順でソート
limit 10000000 // 結果を最大1000万件に制限次の図は、クエリの結果の例を示しています。

メッセージトレースをクエリする
Simple Log Service の検索ボックスにクエリステートメントを入力して、メッセージトレースをクエリします。
メッセージ ID でメッセージトレースをクエリする
InstanceId:amqp-cn-i7m29o3s**** and VHost:cycle**** and ResourceName:msgId=27127757-44dc-4373-afc5-f8ea12f****次の図は、クエリの結果の例を示しています。

クライアントが
BasicConsumeメソッドを呼び出すことによってメッセージをサブスクライブすると、メッセージの送信とプッシュを記録するメッセージトレースをクエリできます。クエリされたメッセージログでは、値SendMessageはクライアントでのBasicPublishメソッドの呼び出しを示し、値PushMessageはブローカーによるクライアントへのメッセージのプッシュを示します。クライアントがBasicGetメソッドを呼び出すことによってメッセージをプルする場合、メッセージログの Action パラメーターの値はPushMessageではなくBasicGetになります。説明返されたメッセージログに、
SendMessageが1つのログエントリにのみ記録されているが、PushMessageまたは BasicGet が複数のログエントリに記録されている場合、クライアントはBasicAckメソッドを呼び出して有効期間内にメッセージの消費を確認できなかった可能性があります。クライアントは、メッセージが最初に送信された後、消費タイムアウト期間内に BasicAck メソッドを呼び出した場合にのみ、メッセージの消費を確認できます。有効期間外に BasicAck メソッドが呼び出された場合、ブローカーはクライアントがメッセージを消費できなかったと判断し、メッセージを再度プッシュします。消費タイムアウト期間の詳細については、「インスタンス再試行ポリシーのパラメーター」をご参照ください。SendDlqMessageがSendMessageおよびPushMessageに加えて記録されている場合、メッセージはデッドレター queue に送信されました。
メッセージが消費されているかどうかをクエリする
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" // 特定のメッセージが消費されたかどうかを確認するためのクエリConnectionId、ChannelId、deliveryTag、および RemoteAddress パラメーターの値は、
PushMessageを記録するログエントリに基づいて取得できます。RemoteAddress はクライアントの IP アドレスを指定します。ConnectionId は接続の一意の識別子を指定します。ChannelId はチャネルの一意の識別子を指定します。deliveryTagは、ブローカーによってメッセージに追加された一意の識別子を指定します。DeleteMessageがログに記録されている場合、メッセージはクライアントによって消費されます。次の図は、クエリの結果の例を示しています。
説明クライアントが
BasicConsumeメソッドをautoAck=false設定で呼び出した場合、ブローカーは、クライアントがBasicAckメソッドを呼び出した後にのみ、メッセージの消費を確認してメッセージを削除できます。クライアントは、メッセージが最初に送信された後、消費タイムアウト期間内にBasicAckメソッドを呼び出した場合にのみ、メッセージの消費を確認できます。有効期間外に BasicAck メソッドが呼び出された場合、ブローカーはメッセージが消費されなかったと判断し、メッセージをクライアントに再度プッシュします。詳細については、「インスタンス再試行ポリシーのパラメーター」をご参照ください。クライアントが
BasicAckメソッドを呼び出してもDeleteMessageがログに記録されない場合、メッセージは消費されませんでした。この場合、PushMessageメソッドが呼び出された時刻とBasicAckメソッドが呼び出された時刻の差を確認できます。差が消費タイムアウト期間よりも大きい場合、BasicAckメソッドの呼び出しは無効です。PushMessageとDeleteMessageのみがログに記録されている場合、クライアントはBasicAckメソッドをdeliveryTag, multiple=true設定で呼び出した可能性があります。この設定は、ブローカーが一度にdeliveryTagより前のすべてのメッセージの消費を確認することを示します。
queue 内のメッセージの消費をクエリする
Simple Log Service の検索ボックスにクエリステートメントを入力して、SendMessage、PushMessage または BasicGet、BasicAck、および DeleteMessage メソッドのログをクエリします。Simple Log Service は、メソッド呼び出しの合計に対する各メソッドのパーセンテージシェアを計算します。各メソッドのシェアが同じかほぼ等しい場合、メッセージは同様のレートで送受信されます。これは、 queue にメッセージが蓄積されていないか、少数のメッセージが蓄積されていることを示します。
InstanceId:amqp-cn-i7m29o3s**** and Vhost:cycle**** and Queue: cycleCheckQueue**** and (SendMessage or PushMessage or BasicAck or DeleteMessage)次の図は、クエリの結果の例を示しています。

クエリされたメッセージログで次のいずれかのシナリオが発生した場合、次の説明に基づいて原因を分析します。
DeleteMessageがログに記録されていない場合は、クライアントがBasicConsumeまたはBasicGetメソッドをautoAck=true設定で呼び出したか、消費タイムアウト期間内にメッセージを確認するためのリクエストの処理に失敗した可能性があります。消費タイムアウト期間の詳細については、「インスタンス再試行ポリシーのパラメーター」をご参照ください。PushMessageメソッドへの呼び出しの割合がSendMessageメソッドへの呼び出しの割合よりも大幅に少ない場合、メッセージをサブスクライブするコンシューマーの数が少なすぎる可能性があります。この場合、より多くの接続を確立し、より多くのコンシューマーを作成することをお勧めします。SendMessageメソッドへの呼び出しの割合がPushMessageメソッドへの呼び出しの割合とほぼ等しく、DeleteMessageメソッドへの呼び出しの割合が SendMessage メソッドまたは PushMessage メソッドへの呼び出しの割合よりも大幅に小さい場合、クライアントは消費タイムアウト期間内にメッセージを確認するためのリクエストの処理に失敗した可能性があります。消費タイムアウト期間の詳細については、インスタンス再試行ポリシーのパラメーター をご参照ください。SendMessage、PushMessage、およびDeleteMessageメソッドへの呼び出しの割合がほぼ等しく、BasicAckメソッドへの呼び出しの割合が小さい場合、クライアントはmultiple=true設定で BasicAck メソッドを呼び出している可能性があります。
配信不能キュー内のメッセージのログを照会する
Simple Log Service の検索ボックスにクエリステートメントを入力して、配信不能キュー内のメッセージのログを照会します。
メッセージの有効期限 (TTL) が終了した後に配信不能キューに送信されたメッセージのログを照会する
InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and ResourceName:msgId=02a162ba-f842-440f-bfd4-2595dd19****次の図は、クエリの結果例を示しています。

SendMessageの値は、クライアントがBasicPublishメソッドを呼び出してメッセージを送信したことを示します。SendDlqMessageの値は、メッセージの TTL が終了した後にメッセージが配信不能キューに送信されたことを示します。説明配信不能キューが設定されている場合にのみ、SendDlqMessage がログに記録されます。
キューの 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]); // キューの TTL を設定します channel.queueDeclare([queueName], true, false, false, argument); // キューを宣言しますSimple Log Service の検索ボックスに次の情報を入力して、
SendMessageとSendDlqMessageのログを照会します。InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and ResourceName:msgId=034a75c5-d957-422f-822e-72dfad2a****
クライアントが
requeue=false設定でBasicRejectメソッドまたはBasicNackメソッドを呼び出した場合は、次の情報を入力して SendDlqMessage のログを照会します。InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and (ResourceName:msgId=034a75c5-d957-422f-822e-72dfad2a**** or ResourceName:deliveryTag=1)
前の図では、
PushMessageのログエントリは、ブローカーがクライアントにメッセージをプッシュしたことを示しています。クライアントがメッセージを受信した後、クライアントは requeue=false 設定でBasicRejectメソッドを呼び出します。SendDlqMessageがログに記録されている場合、メッセージは配信不能キューに送信されます。