2013-01-08 55 views
2

我已經看到這個問題的點點滴滴,但沒有直接回答它。羣集環境中JMS主題的HTTP使用者

這裏是假設的環境:

  • 20的Java中心的服務器(即Tomcat的/ Glassfish的/ Jboss的/其他) 經由HTTP與客戶說話
  • 中的服務器前的HTTP負載平衡器是不是保證到 帶你回到同一個服務器與每個客戶端連接。
  • 其他任何技術都是明智的。 (JMS /駱駝/ 的Memcached/Hazelcast /不管)

我們希望喬和他的瀏覽器(可能使用Flash或HTML5或任何客戶端技術)來接收發布到可用的JMS主題的所有20的所有消息服務器。

下面是一個例子:

  • 喬的第一個HTTP連接命中服務器A
  • 服務器A現在有喬HTTP會話(通過cookie等)
  • 服務器A訂閱他的話題(基於他的會話ID等)
  • Joe的HTTP連接結束。
  • 消息發佈到主題。
  • 喬使得另一個連接,但這次它是由服務器F.

這就是事情對我來說有點模糊處理。

  • 我們知道他退回時Joe的會話ID(也許會話在所有服務器之間共享),但JMS訂閱又如何?如果服務器F必須再次向該主題訂閱Joe,他是否錯過了一條消息?是Joe可以從中檢索這條消息的唯一服務器,或者當他在F上訂閱時它可能會發生某種魔法,並且它只知道他沒有收到該消息(可能在A上等待他)。

我想我有點不清楚什麼「訂閱」(處理方式)以及它與集羣服務器的關係。我正在使用長輪詢(cometd)和websockets來幫助客戶端在接收主題消息時的響應能力,但是當有許多服務器可以處理連接和訂閱時,必須考慮這將如何工作。我想避免服務器鎖定。

感謝您的指點。

編輯1:希望澄清一些。 BlazeDS框架中提供了一些特定的內容。它允許HTTP客戶端訂閱JMS主題並使用長輪詢實現近實時的客戶端更新,但它要求客戶端訪問服務器後,所有請求都必須返回到該服務器。所以它必須(以某種方式)保持該服務器上該客戶端的主題訂閱處於活動狀態。我想擺脫這一要求(使用任何技術/框架)。

回答

4

JMS服務器會跟蹤所做的每一次訂閱,並對持久訂閱與非持久訂閱進行區分。假設你有用戶A,B,C和一個主題T.

  1. 客戶端A訂閱主題T和等待消息
  2. 客戶端B訂閱話題牛逼等待消息
  3. 客戶端C劑量耐用訂閱主題T和的消息
  4. 等待
  5. 客戶B和C消息M放在主題牛逼之前崩潰秒
  6. 客戶端A得到消息M的副本,因爲它是認購,當前連接到JMS服務器
  7. 客戶端B重新啓動但沒有得到郵件的副本,因爲郵件到達主題時沒有連接到jms服務器
  8. 客戶端C重新啓動並獲取消息M,因爲它交付了持久訂閱,JMS服務器保留消息M的副本,而C被毀壞並等待C回來並要求消息。

在消息服務器上有一些管理設置,用於控制jms服務器在發送消息到死信隊列之前等待持久訂閱者返回並聲明消息的時間長度或最大數量的關於正在等待訂戶回來並主張的主題的消息。你真的需要平衡消息與流消息之間的鬆散,以及內存不足或磁盤空間不足。

請注意,持久隊列的概念不同於持久訂閱者的概念。持久隊列和主題通過在確認收到消息之前將隊列和消息的內容寫入磁盤來保護您免受JMS服務器的崩潰。持久訂閱者是指消息在客戶端未連接時到達時發生的消息。


舊的回答。

想想JMS服務器的方式,你想到一個SQL數據庫。從Web容器的角度來看,應該有一個到JMS服務器的連接池,所以你要做的就是獲取到JMS服務器的連接並訂閱一個主題。例如。

  • JMS服務器有一個名爲AddressChangeTopic一個話題
  • 每個Tomcat實例有一個訂閱AddressChangeTopic
  • 喬/吉姆/約翰...等所有地址更改事件去同AddressChangeTopic,而不是去JohnAddressTopic,JimAddressTopic等等,爲每個用戶爲應用程序創建一個單獨的主題將是不切實際的,如果你有100萬用戶,你會有100萬個主題嗎?

因此,如果正在使用一個主題,你必須消耗使用選擇性消費者從該主題的信息,請參閱http://www.eaipatterns.com/MessageSelector.html什麼選擇性消費者需要做的是從符合特定標準的話題retrive消息。例如,向主題發佈JMS消息的消息生產者應該包含一個名爲targetUser或類似的JMS屬性,那麼消費者可以說給出了來自AddressChangeTopic的任何消息,其中定製屬性targetUser =「Joe」查看一些示例選擇器示例Here

這樣做的關鍵是要意識到您可以通過查詢某個隊列或主題的方式查詢數據庫表,但查詢語法有限。從概念的角度來看,我強烈建議企業集成模式圖書http://www.amazon.ca/Enterprise-Integration-Patterns-Designing-Deploying/dp/0321200683

+0

感謝您的回覆。我熟悉EIPs/Camel以及如何查詢JMS以過濾或路由特定消息(即ActiveMQ/RabbitMQ)。我的問題更多地涉及訂閱在系統A上發生時發生的情況,然後我們在不同的系統上創建新的訂閱。如果我在不同的系統上有多個訂閱(使用相同的過濾器),我會丟失消息嗎? (或者JMS足夠聰明,知道當我切換機器時我還沒有使用主題消息)。 – h1d3m3

+0

@ h1h3m3現在我已經改變了我的答案,我更瞭解你的問題,希望我的回答是你正在尋找的。 – ams

+0

再次感謝您的更新,但仍然不是我所需要的。我需要更好地描述我的問題。這不一定是關於耐用性,而是關於訂閱。如果我訂購了服務器A(並且它在該服務器的內存中處於活動狀態),那麼將失去與服務器A的連接,並連接到服務器B(該服務器尚未與我的主題建立連接),B會收到正在等待的消息或者已經消耗了它?我有點不清楚「有效訂閱」實際上意味着什麼時候沒有活動http連接(即已訂閱,但不能接收) – h1d3m3