隨著Internet服務的發展,其分布越來越廣泛,這使得企業消息傳遞逐漸成為Web應用基礎架構最重要的部分之一。應用程序可以在短時間內傳輸大量的消息,而且通常傳輸的數據是底層的業務流程非常必需的。
但是,無論這些數據有多么重要,很多企業應用程序的配備不足以使它們在碰到常見的消息傳遞問題時恢復正常。當然,消息可以保存在數據存儲區中,但系統經常缺少可靠且足夠靈活的監控和治理機制——像失敗消息的適當處理這么重要的功能也可能被忽略掉。
本文將從治理的角度討論WebLogic消息傳遞和java消息服務(Java Message Service,JMS)。我們將看看如何給予業務要害型消息以應有的關注,以及如何使用治理工具確保應用程序的消息流順暢無阻。
企業應用程序中介體
企業消息傳遞基本上全是異構系統間的數據交換,是一種計算機間通信形式,它始終都需要專門的措施以確保其成功運行。假如缺少某種中介體,那么維護跨網絡的進程間通信會非常困難,因此我們使用諸如WebLogic JMS之類的面向消息中間件(message-oriented-middleware,MOM)系統來為我們解決保證交付、消息通知以及其他所有的固有復雜問題??梢詫OM視為企業應用程序的郵政服務。
Weblogic JMS是一種高度可靠的服務,假如它對已發送的消息做出確認,那么用戶就完全可以確信該消息已被接收。但是,確切地說,保證就到此為止了;客戶端應用程序(消息生產者)無法了解接收端應用程序(消息消費者)是否已成功地處理了該消息,除非用戶實現自己的確認系統。
假如存在問題,那到底是什么問題呢?
只要兩臺計算機進行通信,那么遲早會出現故障。無法訪問子系統、網絡故障、消息溢出、死鎖等等,這些全是用戶可能碰到的一些常見問題。不要試圖保證永遠不會發生故障,而是要確保做好應對故障的預備。需要針對每一種處理失敗的情況找出其各自的糾正措施。通過自動重試可以很輕易地修復某些問題(如:子系統忙),而另外一些問題則需要人工干預。況且,許多服務不支持任何形式的重新處理或錯誤處理等,這使得故障恢復必須由客戶端應用程序來完成。
我們假設:用戶的業務模型將首先使用戶盡一切可能處理消息,不行的話才會放棄并向客戶端應用程序發出否定確認。在這種情況下,用戶可能要自動重試幾次處理;若無效,那么應有人能夠對失敗消息做人工檢查。現在來看一種在實踐中達成此目的的常見方法。
消息治理的兩種方法
一種非常健壯的消息治理技術是將全部的失敗消息發送至一個錯誤隊列,并讓消費者將其包括的數據和屬性保存到一個數據庫中。隨后,治理員會對該消息進行分析,并選擇是否要重新創建消息,然后再次發送。使用數據庫來存儲消息使得數據具有高度完整性且操作方便。下面是該實現所需的主要步驟:
1.在config.xml文件中為目的地配置一個持久性錯誤隊列。錯誤隊列又稱為死消息隊列,失敗消息將被自動發送到這個常規JMS目的地。通過在用戶的當前目的地(active destination)中添加ErrorDestination參數可將消息定向至錯誤隊列。
2.為錯誤隊列配置消費者,通過使用javax.jms.Message類的accessor方法使其讀取已存儲的失敗消息的數據和屬性。
3.將恢復性數據與消息的原始目的地名稱一起保存到一個數據庫表格中。可以通過使用Message類的getJMSDestination()方法獲得原始目的地。
4.編寫幾個方法,以便從數據庫讀取數據,顯示數據,通過根據已保存的數據重新創建消息、并將其發送至原始目的地,從而提供重新發送消息的選擇。
完成上述步驟后,就可以得到一個非常靈活的治理消息傳遞問題的系統。該實現需要大量的工作,但是假如用戶熟悉JMS并了解其基本知識,那么執行起來就十分簡單。雖然這種解決方案非常不錯并且經常被使用,但是還有一種更易于實現的方法,它無需使用數據庫,并且可以為用戶提供額外的好處,即,可以使用戶在運行時看到任何隊列的內容。
用于瀏覽隊列的QueueBrowser
JMS API中包括支持全面訪問排隊消息的工具。下面要討論的工具是javax.jms.AueueBrowser接口及消息選擇器(message selector)。QueueBrowser是一種可在給定隊列中檢索消息而不消費這些消息的接口。它可返回全部消息,在消息選擇器的幫助下還可以返回全部消息的一個子集。
另一種可供選擇的隊列治理方法是使用消極錯誤隊列來存儲失敗消息,并使用QueueBrowser列出這些失敗消息。然后可挑選出單個消息,對其進行重新發送、復制或刪除操作。
下文是關于開發簡單的處理失敗消息的隊列治理系統的分步說明:
在config.xml文件中為目的地配置持久性錯誤隊列。不需要為錯誤隊列配置或編寫任何消費者。
使用QueueBrowser接口顯示錯誤隊列中的全部消息。對隊列中消息的瀏覽非常簡單,只需編寫幾行代碼即可實現(見清單)。
清單1:瀏覽隊列內容
public Enumeration getQueuedMessages(
javax.jms.Queuesession qSession,
javax.jms.Queue queue)
throws javax.jms.JMSException
{
javax.jms.QueueBrowser browser =
qSession.createBrowser(queue);
return browser.getEnumeration();
}
新聞熱點
疑難解答