2011-06-03 26 views
5

我有哪裏的消息保持每小時70K個XML的速度來的應用程序。我們使用這些XML消息並將其存儲到中間隊列中。創建中間隊列是因爲我們需要滿足在24小時內消費所有消息的SLA。我們能夠在24小時內將XMLS消費並加載到內部隊列中。在將其加載到內部隊列後,我們處理XMLS(解析,應用很少的轉換,執行很少的驗證)並將數據存儲到嚴格標準化的數據模型。我知道數據模型會對性能產生巨大影響,但不幸的是,我們無法控制數據模型。目前,我們花費3.5分鐘處理2K消息,這是不可接受的。我們希望將它降至1分鐘以獲得2K消息。下面是我們迄今所做的:如何提高基於MQ的批處理應用程序的性能?

1)應用指標(如適用)。
2)使用XMLBeans用於解析個XML(大小每個XML不是很龐大)
3)移除所有不必要的驗證,transformatios等

的應用上運行:
操作系統:RHEL 5.4 64位
平臺:JDK 1.6.0_17中,64位
數據庫:的Oracle 11g R2的64位(2節點羣集)
外部MQ:IBM隊列
內部的臨時存儲MQ:JBoss的MQ
應用服務器:Jboss的5.1。 0.GA(EAP版)

中,我們消耗和處理XML消息的順序是非常重要的,所以我們不能做並行處理。

還有什麼事情我們可以做,以提高性能?

回答

1

的WebSphere MQ,甚至一個小的服務器上,可以卸載的消息遠比你所描述的速度更快。 Windows Performance Report for WMQ V7通過客戶端頻道每秒超過2200次2k次持續往返測試(一次請求和一次回覆)進行測試。這是每秒超過4,000條消息。

你的情況的瓶頸似乎是處理消息的延遲和在一個特定的順序處理消息的依賴。可以爲您提供最高性能提升的選項是消除順序依賴關係。當我在一家銀行工作時,我們有一個系統按照他們到達的確切順序發佈交易,所有人都表示這個要求是強制性的。但是,我們最終修改了系統,在白天執行備忘錄,然後在稍後的步驟中重新發布。備忘錄發佈以任何順序發生,並支持並行,故障轉移和多實例處理的所有其他好處。最後一篇文章按照邏輯順序應用交易(事實上,對於客戶來說,這是最有利的一個訂單),一旦他們都在數據庫中。序列依賴性將您鎖定爲單例模型,並且是異步消息的最壞情況要求。儘可能消除它們。

另一個需要改進的地方是解析和處理消息。只要您遇到順序依賴關係,這是提高性能的最佳選擇。

最後,您總是可以選擇以更多內存,CPU,更快的磁盤I/O等形式向問題拋出金錢。從本質上講,這是針對具有馬力的軟件架構,永遠不是最好的解決方案,但通常它會讓您花足夠的時間來解決根本原因。

+0

正如您所說,MQ Websphere的性能非常好。您提到的問題在嘗試處理消息時發生。目前,我們沒有奢侈的重新發布信息,所以我們堅持1張單獨發帖。所以看起來像我陷入了沒有更多的額外道路。在硬件上花錢也是一樣。我會嘗試在每個消息處理中引入並行性。無論如何,只是想確保我已經覆蓋了一切。 – SJoe 2011-06-03 14:44:40

2

消息傳遞微調之外的一些建議,因爲它似乎這不是你的[PRIMARY]瓶頸:

  • 您曾提到自己將數據存儲到一個高度規範化的數據庫。這總是意味着一個或多個引用數據或PK查找,這些引用數據或PK查找會爲數據庫創建多個附加行程以獲取此數據。爲避免或減少這種情況,請創建一個包含所有參考數據的本地緩存,並隨時更新緩存。在內存查詢中,將比訪問數據庫的速度快得多。
  • 如果你覺得你沒有足夠的內存來緩存所有的解碼和參考數據,打一槍換一個基於磁盤的緩存(如的EHCache將做RAM,磁盤或溢出)或輕的本地數據庫像超音速或H2將仍然給你更好的查找時間比去一趟甲骨文(除非你是在同一主機上,即使這樣......)
  • 最終,如果每封郵件需要多次往返到數據庫,你可以從遷移處理中受益的消息傳遞給數據庫本身,您可以在PL/SQL或Java中實現該過程。
  • 如果您爲一條處理的消息寫入數據庫涉及多個插入/更新,請確保使用準備好的語句批處理。這將在一次調用中向數據庫發送多個插入/更新。
  • 說起準備的語句,請確保您的JBoss DataSource configuration對於Oracle有準備語句緩存大小設置爲某個數字不足以滿足要求,在加工過程中(而不是默認的是零,或者創建了所有準備的語句無高速緩存)。
  • 您正在使用的XML解析器可能會施加比所需更多的開銷,即使(或尤其)對於小消息。如果您使用的是JAXB,請確保您不是一次(或多次)不重新創建解組器。或者,嘗試一下Pull/Streaming parser。如果您使用的是DOM解析器,則所需的額外內存可能會導致大量垃圾回收。
  • 愚蠢的事情,但值得一提的是,如果在執行了很多記錄的每個消息,將要花費你的時間,所以把它關掉。
  • 使用JBoss MQ作爲中介緩衝區是優雅,但它可能不是存儲郵件遞延處理,因爲持久性是各種JMS消息類型的更復雜的和廣義的最快方法。在那個說明中,如果JBoss MQ堅持Oracle,那麼自定義持久化過程似乎不可能更快。如果JBoss MQ正在存儲到HyperSonic中(如默認情況下那樣),您仍然可能使用一些自定義代碼勝過JMS消息的存儲。這也意味着您需要一種新的機制將消息從數據庫中提取出來進行處理,但與JMS存儲一樣,定製過程可能會勝過JBoss MQ實現的更一般化的過程。
  • 存儲中介的消息在DB也可以提供更多的靈活性,查詢,以確定消息沒有被串行處理。 (例如,也許,來自不同客戶端的消息不需要按順序處理)。當然,你也可以通過在中間消息中放置適當的頭文件來實現這一點。這將允許您通過在多個不同的消息偵聽器/處理器中使用不同的選擇器來並行化。在消息

一個快速的項目.....

如果你使用的消息驅動bean與WebSphere MQ你沒有提到,但如果你是,就在Inbound Configuration稱爲在PollingInterval其中,從文檔引用的設置,是指:

如果會話中的每個消息偵聽器在其隊列中沒有合適的消息,則這是在每個消息偵聽器再次嘗試從其隊列中獲取消息之前經過的最大時間間隔(以毫秒爲單位)。如果經常發生沒有合適的消息可用於會話中的任何消息偵聽器,請考慮增加此屬性的值。只有當TRANSPORT具有BIND或CLIENT值時,此屬性纔是相關的。

默認pollingTime是5000毫秒。您當前的消息處理時間是

(3.5 * 60 * 1000/2000)的每個消息

= 105毫秒。

如果您在此處引入5000 ms的暫停,這將嚴重降低吞吐量,因此您可能需要通過測量消息入隊時間和接收時間之間的持續差異來查看此情況JBoss消息偵聽器中的消息。入隊時間可以從這些郵件頭確定:

  • JMS_IBM_PutDate
  • JMS_IBM_PutTime

總而言之,你最好的選擇將是找出如何並行。

祝你好運。

// Nicholas

+0

謝謝。我會看到哪些可以用於我的情況。 – SJoe 2011-06-07 15:25:09