すべてのプロダクト
Search
ドキュメントセンター

ApsaraMQ for RabbitMQ:トラブルシューティングのための一般的なクエリステートメント

最終更新日:Jan 14, 2025

このトピックでは、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万件に制限

次の図は、クエリの結果の例を示しています。image

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万件に制限

次の図は、クエリの結果の例を示しています。

image

メッセージトレースをクエリする

Simple Log Service の検索ボックスにクエリステートメントを入力して、メッセージトレースをクエリします。

  • メッセージ ID でメッセージトレースをクエリする

    InstanceId:amqp-cn-i7m29o3s**** and VHost:cycle**** and ResourceName:msgId=27127757-44dc-4373-afc5-f8ea12f****

    次の図は、クエリの結果の例を示しています。

    image

    クライアントが BasicConsume メソッドを呼び出すことによってメッセージをサブスクライブすると、メッセージの送信とプッシュを記録するメッセージトレースをクエリできます。クエリされたメッセージログでは、値 SendMessage はクライアントでの BasicPublish メソッドの呼び出しを示し、値 PushMessage はブローカーによるクライアントへのメッセージのプッシュを示します。クライアントが BasicGet メソッドを呼び出すことによってメッセージをプルする場合、メッセージログの Action パラメーターの値は PushMessage ではなく BasicGet になります。

    説明
    • 返されたメッセージログに、SendMessage が1つのログエントリにのみ記録されているが、PushMessage または BasicGet が複数のログエントリに記録されている場合、クライアントは BasicAck メソッドを呼び出して有効期間内にメッセージの消費を確認できなかった可能性があります。クライアントは、メッセージが最初に送信された後、消費タイムアウト期間内に BasicAck メソッドを呼び出した場合にのみ、メッセージの消費を確認できます。有効期間外に BasicAck メソッドが呼び出された場合、ブローカーはクライアントがメッセージを消費できなかったと判断し、メッセージを再度プッシュします。消費タイムアウト期間の詳細については、「インスタンス再試行ポリシーのパラメーター」をご参照ください。

    • SendDlqMessageSendMessage および 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" // 特定のメッセージが消費されたかどうかを確認するためのクエリ            

    ConnectionIdChannelIddeliveryTag、および RemoteAddress パラメーターの値は、PushMessage を記録するログエントリに基づいて取得できます。RemoteAddress はクライアントの IP アドレスを指定します。ConnectionId は接続の一意の識別子を指定します。ChannelId はチャネルの一意の識別子を指定します。deliveryTag は、ブローカーによってメッセージに追加された一意の識別子を指定します。DeleteMessage がログに記録されている場合、メッセージはクライアントによって消費されます。

    次の図は、クエリの結果の例を示しています。查询消息是否被消费

    説明

    クライアントが BasicConsume メソッドを autoAck=false 設定で呼び出した場合、ブローカーは、クライアントが BasicAck メソッドを呼び出した後にのみ、メッセージの消費を確認してメッセージを削除できます。クライアントは、メッセージが最初に送信された後、消費タイムアウト期間内に BasicAck メソッドを呼び出した場合にのみ、メッセージの消費を確認できます。有効期間外に BasicAck メソッドが呼び出された場合、ブローカーはメッセージが消費されなかったと判断し、メッセージをクライアントに再度プッシュします。詳細については、「インスタンス再試行ポリシーのパラメーター」をご参照ください。

    • クライアントが BasicAck メソッドを呼び出しても DeleteMessage がログに記録されない場合、メッセージは消費されませんでした。この場合、PushMessage メソッドが呼び出された時刻と BasicAck メソッドが呼び出された時刻の差を確認できます。差が消費タイムアウト期間よりも大きい場合、BasicAck メソッドの呼び出しは無効です。

    • PushMessageDeleteMessage のみがログに記録されている場合、クライアントは BasicAck メソッドを deliveryTag, multiple=true 設定で呼び出した可能性があります。この設定は、ブローカーが一度に deliveryTag より前のすべてのメッセージの消費を確認することを示します。

queue 内のメッセージの消費をクエリする

Simple Log Service の検索ボックスにクエリステートメントを入力して、SendMessagePushMessage または 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)

次の図は、クエリの結果の例を示しています。

image

クエリされたメッセージログで次のいずれかのシナリオが発生した場合、次の説明に基づいて原因を分析します。

  • DeleteMessage がログに記録されていない場合は、クライアントが BasicConsume または BasicGet メソッドを autoAck=true 設定で呼び出したか、消費タイムアウト期間内にメッセージを確認するためのリクエストの処理に失敗した可能性があります。消費タイムアウト期間の詳細については、「インスタンス再試行ポリシーのパラメーター」をご参照ください。

  • PushMessage メソッドへの呼び出しの割合が SendMessage メソッドへの呼び出しの割合よりも大幅に少ない場合、メッセージをサブスクライブするコンシューマーの数が少なすぎる可能性があります。この場合、より多くの接続を確立し、より多くのコンシューマーを作成することをお勧めします。

  • SendMessage メソッドへの呼び出しの割合が PushMessage メソッドへの呼び出しの割合とほぼ等しく、DeleteMessage メソッドへの呼び出しの割合が SendMessage メソッドまたは PushMessage メソッドへの呼び出しの割合よりも大幅に小さい場合、クライアントは消費タイムアウト期間内にメッセージを確認するためのリクエストの処理に失敗した可能性があります。消費タイムアウト期間の詳細については、インスタンス再試行ポリシーのパラメーター をご参照ください。

  • SendMessagePushMessage、および DeleteMessage メソッドへの呼び出しの割合がほぼ等しく、BasicAck メソッドへの呼び出しの割合が小さい場合、クライアントは multiple=true 設定で BasicAck メソッドを呼び出している可能性があります。

配信不能キュー内のメッセージのログを照会する

Simple Log Service の検索ボックスにクエリステートメントを入力して、配信不能キュー内のメッセージのログを照会します。

  • メッセージの有効期限 (TTL) が終了した後に配信不能キューに送信されたメッセージのログを照会する

    InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and ResourceName:msgId=02a162ba-f842-440f-bfd4-2595dd19****

    次の図は、クエリの結果例を示しています。

    image

    SendMessage の値は、クライアントが BasicPublish メソッドを呼び出してメッセージを送信したことを示します。SendDlqMessage の値は、メッセージの TTL が終了した後にメッセージが配信不能キューに送信されたことを示します。

    説明

    配信不能キューが設定されている場合にのみ、SendDlqMessage がログに記録されます。

  • キューの TTL が終了した後に配信不能キューに送信されたメッセージのログを照会する

    1. キューの配信不能属性と 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); // キューを宣言します
    2. Simple Log Service の検索ボックスに次の情報を入力して、SendMessageSendDlqMessage のログを照会します。

      InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and ResourceName:msgId=034a75c5-d957-422f-822e-72dfad2a****

      image

  • クライアントが requeue=false 設定で BasicReject メソッドまたは BasicNack メソッドを呼び出した場合は、次の情報を入力して SendDlqMessage のログを照会します。

    InstanceId:amqp-cn-i7m29o3s**** and VHost:dlq**** and (ResourceName:msgId=034a75c5-d957-422f-822e-72dfad2a**** or ResourceName:deliveryTag=1)

    image

    前の図では、PushMessage のログエントリは、ブローカーがクライアントにメッセージをプッシュしたことを示しています。クライアントがメッセージを受信した後、クライアントは requeue=false 設定で BasicReject メソッドを呼び出します。SendDlqMessage がログに記録されている場合、メッセージは配信不能キューに送信されます。