PHP如何取得ActiveMQ的狀態

在測試ActiveMQ過程中,發現發生下面狀況時,ActiveMQ可能就會出現異常的狀況
  1. 當queue內累積過多的筆數
  2. 當queue內累積太多的資料內容
要多少筆數?多少資料量?才可能出現異常呢?官方資料中,沒有找到明確的數據。

根據測試的經驗,這個數字依舊和機器等級有差。當procedure往queue塞資料的速度大於consumer消化速度,讓queue內的資料筆數一直累積上去。會導致consumer處理速度越來越慢、惡性循環下去。其實,procedure的處理能力,也會越來越差。

如果queue繼續累積下去,會出現無法連到ActiveMQ。甚至WEB管理介面也失效、最後要重新啟動ActiveMQ。最慘的狀況是,當重新啟動後,還要將剛剛的queue刪除,才能恢復正常。

也曾遇過一個狀況,ActiveMQ的主機,最後因stock吃完而無法服務。

因此,需要監控ActiveMQ的狀況。或者,在procedure中檢查queue內的數量,作為後續處理的依據。(當然,還是要看怎麼規劃、運用ActiveMQ)

如何以PHP+STOMP取得ActiveMQ的資訊呢?
  1. 開啟ActiveMQ的statistics plugin。作法請參考Apache ActiveMQ -- StatisticsPlugin
  2. 訂閱ActiveMQ.Statistics.Destination.< destination-name >(或ActiveMQ.Statistics.Destination.< wildcard-expression >),並送出空字串
  3. 如果照上述官方文件實作,會有問題。因為裡面的範例是JMS。STOMP所使用的header名稱和JMS的不同,依據Stomp extensions for JMS message semantics內所述。需將JMSReplyTo改為reply-to。
  4. 最後,還要將MapMessage改成JSON格式。讓PHP能處理

最後,簡單的php code,如下
  1. function getMQStatus($queue) {  
  2.     $result = $num = FALSE;  
  3.     $statusqueue = "/queue/ActiveMQ.Statistics.Destination.{$queue}";  
  4.   
  5.     //開啟ActiveMQ  
  6.     $link = openMQ();  
  7.     if (FALSE !== $link) {  
  8.         //查詢之後的結果存放處  
  9.         $resultqueue = "/queue/test-status_{$queue}";  
  10.   
  11.         //設定採用JSON格式  
  12.         stomp_subscribe($link$resultqueuearray"transformation" => "jms-map-json"));  
  13.         //送出空字串  
  14.         $result = stomp_send($link$statusqueue''array("reply-to" => $resultqueue));  
  15.         if (FALSE === $result) {  
  16.             echo " send error~" . PHP_EOL;  
  17.         }  
  18.         //取得狀態  
  19.         while (stomp_has_frame($link)) {  
  20.             $frame = stomp_read_frame($link);  
  21.   
  22.             if (FALSE != $frame) {  
  23.                 stomp_ack($link$frame['headers']['message-id']);  
  24.                 $obj = json_decode($frame['body'], TRUE);  
  25.                 //取得目前數量(尚可取得其他狀態)  
  26.                 foreach ($obj['map'][0]['entry'as $pitem) {  
  27.                     if ('size' == $pitem['string']) {  
  28.                         $num = $pitem['long'];  
  29.                         break;  
  30.                     }  
  31.                 }  
  32.             } else {  
  33.                 //break;  
  34.             }  
  35.         }  
  36.   
  37.         stomp_unsubscribe($link$resultqueue);  
  38.         stomp_close($link);  
  39.     }  
  40.   
  41.     return $num;  
  42. }  

參考資料

  1. Apache ActiveMQ -- StatisticsPlugin
  2. Stomp extensions for JMS message semantics
  3. stomp 1.1和stomp 1.0的差異
  4. ActiveMQ參考書籍-ActiveMQ in Action
  5. php使用stomp操作ActiveMQ
  6. stomp進階說明-prefetchSize、ack header
  7. stomp failover作法
  8. PHP如何取得ActiveMQ的狀態

留言