全部產品
Search
文件中心

ApsaraMQ for RabbitMQ:常用排查定位查詢語句

更新時間:Dec 07, 2024

本文介紹基於雲訊息佇列 RabbitMQ 版當前日誌快速查詢和分析問題的方法。當您遇到訊息不符合預期、消費異常、訊息堆積時,通過該方法可以協助您高效識別出異常、保證業務正常運行。

前提條件

已開啟日誌管理功能並配置索引

常用語句概覽

本文僅列舉常用SLS查詢語句,操作步驟和日誌格式說明,請參見日誌管理

根據Exchange查詢發送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 

查詢結果如下所示:image

根據Queue查詢消費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

查詢結果如下所示:

image

查詢訊息軌跡

在記錄搜尋框中輸入查詢語句,查詢訊息軌跡。

  • 通過Message ID查詢訊息軌跡

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

    查詢結果如下所示:

    image

    用戶端調用BasicConsume訂閱,可以查詢到訊息的發送和服務端的推送軌跡,SendMessage對應用戶端調用BasicPublishPushMessage對應服務端推送訊息給用戶端;如果用戶端採用BasicGet拉取訊息,則ActionBasicGet而不是PushMessage

    說明
    • 如果日誌結果中SendMessage只有一條,但是PushMessage(BasicGet)對應多條,可能是用戶端沒有在首條PushMessage(BasicGet)的消費逾時時間內調用BasicAck確認訊息,導致服務端以為用戶端沒有消費成功而重新推送該條訊息。消費逾時時間說明請參見執行個體重試策略參數說明

    • 如果日誌結果中除了SendMessagePushMessage之外,還存在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"            

    其中,ConnectionIdChannelIddeliveryTagRemoteAddress都是通過PushMessage日誌擷取。RemoteAddress是用戶端的IP地址,ConnectionId是當前Connection的唯一標識,ChannelId是當前Channel的唯一標識,deliveryTag是服務端對當前訊息的唯一標識;DeleteMessage日誌則是用戶端成功消費訊息的標記。

    查詢結果如下所示:查詢訊息是否被消費

    說明

    如果用戶端調用BasicConsume時設定autoAck=false,則需要用戶端調用BasicAck服務端才能確認訊息被用戶端正常消費並刪除,而且BasicAck必須在PushMessage時間戳記之後的消費逾時時間內調用,超過消費逾時時間服務端則認為用戶端消費失敗,並會重新推送該訊息到用戶端。具體請參見執行個體重試策略參數說明

    • 用戶端已經調用BasicAck,但是查詢訊息是否被消費時,發現日誌中並沒有DeleteMessage日誌,說明當前訊息並沒有成功消費,可以觀察PushMessageBasicAck時間差,大於消費逾時時間則表示當前BasicAck是無效調用。

    • 如果只查詢到PushMessageDeleteMessage,沒有查到BasicAck,可能是BasicAck(deliveryTag, multiple=true)一次性Ack了deliveryTag之前的所有訊息。

查詢Queue的消費情況

在記錄搜尋框中輸入查詢語句,查詢SendMessagePushMessage(BasicGet)BasicAckDeleteMessage。當四者的百分比相同的時候,表示用戶端的發送與消費速度基本持平,當前Queue無訊息堆積或是有極少訊息堆積。

InstanceId:amqp-cn-i7m29o3s**** and Vhost:cycle**** and Queue: cycleCheckQueue**** and (SendMessage or PushMessage or BasicAck  or DeleteMessage)

查詢結果如下所示:

image

如果查詢的日誌出現以下幾種情況,請根據可能的原因分析:

  • 記錄搜尋結果中沒有DeleteMessage,可能是由於用戶端在調用BasicConsumeBasicGet時,設定了autoAck=true,或者是用戶端所有的BasicAck請求時間已經超過了消費逾時時間,導致這些調用無效。消費逾時時間說明請參見執行個體重試策略參數說明

  • 記錄搜尋結果中發現PushMessage的百分比相比SendMessage較少,可能是用戶端的訂閱者過少,建議多開Connection並建立新的Consumer。

  • 記錄搜尋結果中發現SendMessagePushMessage的日誌百分比相當,但是DeleteMessage的百分比則相對較少,可能是用戶端存在大量BasicAck的請求時間已經超過了消費逾時時間,變成無效請求。消費逾時時間說明請參見執行個體重試策略參數說明

  • 記錄搜尋結果中發現SendMessagePushMessageDeleteMessage日誌百分比大致相同,但是BasicAck日誌相對較少,考慮是否在代碼中使用了BasicAck(multiple=true)

死信訊息查詢

記錄搜尋框輸入查詢語句,查詢對應訊息。

  • 訊息TTL到期進入無效信件佇列

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

    查詢結果如下所示:

    image

    SendMessage對應您調用BasicPublish發送訊息,SendDlqMessage對應該訊息TTL到期後發送到對應的無效信件佇列中。

    說明

    僅當您配置了無效信件佇列才會有該條日誌。

  • Queue的TTL到期進入無效信件佇列

    1. 設定Queue的死信屬性以及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);
    2. 記錄搜尋框輸入如下,可以得到SendMessageSendDlqMessage日誌。

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

      image

  • 調用BasicRejectBasicNack時,requeue=false

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

    image

    其中PushMessage日誌表示服務端推送訊息到用戶端,用戶端在收到訊息後調用BasicReject(requeue=false),對應SendDlqMessage日誌表示訊息被路由到無效信件佇列中。