2014-05-22 51 views
5

我正在尋找一個奇怪的問題,其中一個緩慢的消費者隊列導致同一隊列上的所有其他使用者開始以30秒的間隔消費消息的幫助。這就是所有的消費者,但速度慢的消費者不會盡可能快地消費信息,相反他們在消費前等待一些神奇的30年代的障礙。一個緩慢的ActiveMQ消費者導致其他消費者緩慢

我的應用程序的基本流程是這樣的:

  1. 一些生產者發生的信息到一個隊列中。消息可以有不同的JMSXGroupIDs
  2. 許多消費者收聽消息對單個隊列
  3. 作爲標準做法JMSXGroupIDs得到分佈在消費者
  4. 在某些點上消費者的一個變慢,無法處理的消息非常快速
  5. 緩慢的消費者最終在代理上填充其預取緩衝區,並且AMQ認識到它在該點處的速度很慢(默認行爲)
  6. - 或者一些「隨機」但稍後關閉時間 - 除緩慢一開始只以相同的30秒間隔消費郵件
  7. 如果接收者很慢變快又那麼事情很快恢復正常運行和上世紀30年代屏障消失

我在爲這可能是導致該問題的損失,或如何解決它,請幫幫我。

更多的背景和結果

  • 我已經成功地可靠地重現上AMQ 5.8.0,5.9.0(在問題最初發現)和5.9.1這個問題,執行全新安裝和現有的操作系​​統管理的安裝,並在不同的機器上有些虛擬機,有些則沒有。所有的Linux安裝,不同的操作系統和Java版本。
  • 它似乎沒有受到與預​​取相關的任何事情的影響,即:將預取值從1更改爲10並不會阻止問題的發生
  • [red herring?]啓用調試日誌amq實例顯示與定期檢查可能過期的消息有關的日誌。該隊列沒有過期策略,所以我只能認爲計劃的時間只是以這樣一種方式喚醒,然後纔將消息發送給非慢速消費者。
  • 如果進入30s模式,則再次進入,然後再次進入秒 - 過去分鐘時間總是相同的,例如過去一分鐘的14秒和44秒。所有消費者和所有託管這些消費者的機器都是如此。這些障礙點在重新啓動amq後會發生變化。
+0

創建單元測試,並打開一個JIRA來和ActiveMQ –

+0

OK問題就行了。我認爲這不是預期的行爲呢? – Matt

+0

https://issues.apache.org/jira/browse/AMQ-5200 - 創建此票以涵蓋此確切情況(即使用羣組而非選擇器),以防其被視爲比修復備選案例更重要 – Matt

回答

2

雖然不嚴格解決問題,但進一步的調查發現了這個問題的根本原因。

TL; DR - 這是已知的行爲和以前Apollo

更多詳細信息

最終,這是由maxPageSize財產和事實AMQ只適用的選擇造成的不固定條件消息在內存中。通常這些是消息選擇器(property = value),但在我的情況下,它們是JMSXGroupID=>Consumer賦值。

作爲消息由隊列接收他們得到分頁到存儲器,並放入集合(在源命名pagedInPendingDispatch)。爲了發送消息,AMQ將掃描這個消息列表,並嘗試找到一個會接受它的消費者。這包括檢查組ID,消息選擇器和預取緩衝區空間。對於我們的用例,我們不使用消息選擇器,但是我們使用組。如果沒有消費者可以接收消息,則它將留在收集中,並在下一個勾號中再次檢查。

爲了阻止pagedInPendingDispatch集合耗盡所有可用資源,建議通過maxPageSize屬性配置此隊列的大小限制。這個屬性實際上並不是最大值,它更像是在正常情況下,新消息到達是應該在內存中分頁還是分頁到磁盤。

有了這兩條信息和一個緩慢的消費者,事實證明pagedInPendingDispatch集合中的所有消息最終只會被慢速消費者消耗掉,因此集合將被有效阻止並且不會派發其他消息。這解釋了爲什麼慢速消費者不受30秒間隔的影響,它已經有maxPageSize消息等待發貨。

這並不能解釋爲什麼我看到的非慢速消費者接收信息每隔30s雖然。事實證明,尋呼消息到存儲器有兩種模式,正常被迫。 Normal遵循上面概述的過程,其中集合的大小與maxPageSize屬性進行比較,但強制時,消息總是被分頁到內存中。此模式允許您瀏覽不在內存中的消息。碰巧這個強制模式也被過期機制所使用,以允許AMQ過期不在內存中的消息。

所以我們現在有什麼是內存中的消息被所有針對派遣同消費者的集合,消費者是不會接受他們,因爲它是緩慢或堵塞。我們還有積壓的消息等待交付給所有消費者。每運行一個expireMessagesPeriod毫秒,強制將消息傳遞到內存中以檢查它們是否應該過期。這將這些消息添加到集合中的頁面上,其中現在包含針對慢速消費者的maxPageSize消息和針對任何消費者的更多消息。這些消息得到傳遞。

QED。

參考