簡體   English   中英

JMS如何在內部工作?

[英]How does JMS Receive work internally?

我一直在研究各種通信技術/體系結構/模式/實現(閱讀:流行語),包括Web服務(WCF,Axis2),ESB,SOA,並希望了解有關消息傳遞的JMS。

從概念上講,JMS聽起來很簡單。 我的看法是它是一個中間代理,管理來自發布者的消息並將它們路由到適當的訂閱者。 這是通過在發布消息時對消息進行排隊,並在收到消息時將它們出列來完成的。

問題1:我對JMS的基本理解是否正確?

在閱讀有關技術時,讓我感到困惑的一件事就是當某個特征(有意或無意)揮手時。

根據我的基本理解,必須運行JMS提供程序才能發送或接收消息。 我對發布的假設是JMS提供程序只是等待消息發布,然后將其存儲在隊列中(內存或數據庫支持,具體取決於實現)。 但是,我不太確定接收是如何工作的。

問題2:如果沒有消息可以接收(通常)阻止?

問題2b:如果是這樣,阻塞是如何實現的? 客戶端是否不斷輪詢消息? 在發布消息之前,服務器是否只是不響應(如何在沒有超時的情況下工作?)提供者是否會向接收者發起呼叫?

問題2c:如果沒有,如何確保及時收到消息,而不影響性能?

基本描述似乎傾向於單個JMS提供程序,以確保集中管理消息而不會丟失。 我可以看到縮放是一個問題。

問題3:JMS如何擴展?

在擴展時,我可以看到存在復雜性以確保將單個消息傳遞給所有適當的訂戶,而不管哪個物理服務器接收到該消息。

問題3b:JMS實施如何確保在規模化環境中可靠交付?

請注意,雖然這些問題與JMS有關,但它們可能適用於任何消息傳遞基礎結構。 我歡迎特定於JMS的答案以及那些更通用或甚至特定於其他技術的答案。

我試圖根據我在JMS上的經驗回答幾個問題。

答案1: - JMS是Java Message Service API; 它為Java客戶端提供了訪問消息傳遞框架的統一接口。 JMS API下面是符合JMS的消息傳遞提供程序,例如WebSphere MQ提供程序。 JMS支持通過任何消息傳遞協議將有效負載傳輸到目標,即。 隊列和主題。 這些是JMS的基礎知識。

怎么收到工作? JMS規范提供了兩個重要的類: - MessageConsumerMessageListener MessageConsumer類允許JMS客戶端通過調用其任何receive()方法來同步接收JMS消息。 在收到消息之前,此調用將阻塞線程。 否則,可以通過向MessageConsumer注冊MessageListener的對象來進行異步接收。 JMSProvider了解消息是否到達其本地目的地,其作用是將消息傳遞給輪詢消息使用者線程或非輪詢注冊消息偵聽器線程。

答案2: - MessageConsumer API有兩種接收變體: receive()receive(long timeout) 后一種變體允許MessageConsumer線程阻塞,直到消息在特定超時時間內到達,否則超時。

不同的消息傳遞框架可能以不同的方式實現阻塞功能。 由於JMS對象是JNDI受管對象,並且提供程序特定的代理對象被返回到JMS客戶端,這意味着客戶端不知道在后台發生阻塞的方式。 特定消息傳遞框架可以在特定時間段之后選擇消息消費者線程輪詢。 或者,它可以選擇阻止直到發送通知。

我不確定您是否正在尋找特定的符合JMS的消息傳遞框架的答案?

答案3: -我想通過JMS擴展你的意思是擁有許多發布者/訂閱者,多個物理機器上的許多目標。 JMS擴展需要支持底層消息傳遞提供程序以支持某種類型的群集/故障轉移。 因此,JMS規范不支持可伸縮性。 如果我錯了,請糾正我? 例如,我參與了符合JMS的WebSphere MQ,它提供了集群支持。

問題1:我對JMS的基本理解是否正確?

讓我們先把術語弄好。 您不能說JMS Provider must be running因為provider是構建JMS服務器的實體,它是必須運行的JMS服務器。 因此,當我們說JMS時,我們指的是提供程序實現的一組API(技術上更為接口)。 所以基本上提供者編寫自己的JMS實現。 例如, Active MQ is a JMS serverApache(provider)提供Active MQ is a JMS server

我對發布的假設是JMS提供程序只是等待消息發布,然后將其存儲在隊列中(內存或數據庫支持,具體取決於實現)。

真的在一定程度上。 遵循不同的模型。 JMS服務器保持套接字打開。 每當發送方客戶端必須發送消息時,它只需打開與套接字的連接並發送消息。 接收行為如何完全不同。 你有拉動推動 在推送服務器中,一旦收到消息,就會將消息推送到實時接收器客戶端。 這也稱為異步模式 在拉模型中,客戶端接收器向服務器發送請求以獲取消息( 同步模式 )。

如果沒有消息可以接收(通常)阻止?

正如我在前面提到的那樣,它將取決於您使用的模型。 接收器將在拉模型中被阻止( 同步接收 )。 這也發生在Session線程中 ,而不是主線程中。

如果是這樣,阻塞是如何實現的? 客戶端是否不斷輪詢消息?

是的,客戶將在拉模型的情況下不斷進行投票。 通常會有超時,客戶端將被終止。

如果沒有,如何在不影響性能的情況下及時確保收到消息?

使用異步模式 您只需注冊一個MessageListener ,當服務器上有消息可用時,它將在其上接收消息onMessage(Message msg)

問題3:JMS如何擴展?

對於提供商而言,這確實是一個令人擔憂的問題。 當您說所有訂戶都收到消息時,您指的是PUBSUB通信模型(其他為PTP )。 在PUBSUB中,發送給主題的消息將被傳遞給訂閱該主題的所有訂閱者。

問題3b:JMS實施如何確保在規模化環境中可靠交付?

可靠性? 不總是。 同樣,這取決於用例。 您可以擁有持久性非持久性消息。 在持久消息的情況下,消息存儲在DB(文件或其他)中,並確保它的傳遞。 在非持久性消息的情況下,沒有這樣的保證。 服務器故障可能導致郵件丟失。

我認為應該提到Queue和Topic之間的區別,因為消息的傳遞方式存在重大差異。

隊列:只有一個客戶端會收到一條消息。 例如,為了向外擴展,您可以將10個客戶端連接到同一個隊列 - 但只有其中一個客戶端將收到特定的消息。 如果沒有連接客戶端,則消息將保留在隊列中,直到有人連接或消息超時。

主題:所有客戶都將收到每封郵件的副本。 通常在訂戶場景中使用,其中許多端點可能對每個消息感興趣。 持久的用戶甚至可能會停機一段時間; 將保留消息,直到訂戶再次啟動或消息超時。 如果沒有連接客戶端且沒有持久訂閱者,則將刪除消息。

JMS支持使用同步方法消息(使用和不使用超時阻塞線程)或使用事件驅動的回調(異步消息偵聽器))。

您可以決定哪種方法更適合您的需求,但您也可能需要查看實際實現。 例如,一些JMS實現為receive()執行網絡往返,因此更好地使用超時或監聽器。

使用消息偵聽器線程行為和暫停消息接收不像阻塞接收調用那樣容易控制。 通常,大多數控制都是通過擁有自己的阻塞receive()調用池來實現的,這些調用具有超時,並分派給您的工作人員。

JMS中有兩種類型的消息傳遞域。

  1. P oint-Ť鄰- P oint(PTP)消息的域
  2. 發布者/訂閱者消息傳遞域

在PTP模型中 ,只有一條消息被傳送到一個接收器。 此處,隊列被用作A M essageöriented 中號 iddleware(MOM)。

隊列負責保留消息,直到接收器准備就緒。

在PTP模型中,發送方和接收方之間沒有時間依賴性。

在此輸入圖像描述


在Pub / Sub模型中 ,一條消息被傳遞給所有訂戶。 這就像廣播。 這里,Topic用作面向消息的中間件,負責保存和傳遞消息。

在PTP模型中,發布者和訂閱者之間存在時間依賴性。

在此輸入圖像描述


JMS編程模型

在此輸入圖像描述

資源


M essage D riven B ean(MDB)

  • MDB是一個包含業務邏輯的bean。 但是,通過傳遞消息來調用它。 所以,它就像JMS Receiver。
  • MDB異步接收消息並對其進行處理。
  • MDB從隊列或主題接收消息。
  • MDB就像無狀態會話bean,它封裝了業務邏輯,並且不維護bean的狀態。

在此輸入圖像描述

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM