閱讀465 返回首頁    go 魔獸


MOM係列文章之 - JMS2 spec. 解讀

     JMS 2是Java EE 7的一個重要“賣點”(如圖所示), 本文的重點也落在了JMS 2規範上,通過近4個小時的閱讀(156 Page),結合最近Common MQ的實施經驗,談談對新規範的一些解讀,後續會陸續發表一些相關博文,希望大家能夠感興趣。



       瀏覽一下Architecture章節目錄,大家很快就會意識到,JMS 2的一個最重要的設計初衷,通過減少編碼提高生產力;通過更高層次的抽象,簡化消息模型。3,4,5,6,7,8,9章節則陸續在消息模型,消息領域,消息發送,消息接收,異常體係,特性工具集等方麵進行詳細闡述。第10,11,12章則重點闡述了JMS broker層麵的一些內在工具API,如何與Java EE應用集成等(包括JTA事務,MDB,Context Injection)。接下來的章節就是Programmer最希望看到的 - 代碼實例薈萃。最後一個章節(也是我這篇文章的開篇),則匯集了JMS version 2的change history。

        從這25條Change List,我們可以歸納出JMS 2.0的幾個亮點(概括起來,就是Simplify,Clarify,Rectify)

(1)Session創建API的簡化,避免了在事務消息下,開發者care消息的AcknowledgeMode。

(2)新增持久消費者創建API,替換JMS1.1裏麵的Domain-specific的API

(3)剔除同一Topic下允許並發消費者消費限製,帶來了更好的可擴展性

(4)延遲投遞,這個特性無疑對於本身就具有異步消費語意的消息係統進一個擴展。

(5)消息異步發送,通過回調函數的形式

(6)兼容Java SE 7的try-with-resource語法,簡化對像的close操作,通過繼承Autocloseable

(7)JMS provider必須設置JMSXDeliveryCount,別小看這個屬性,對Session

acknowledge mode,reliable produce,Qos方麵都有不小的作用

(8)廢除了Message接口中的一些headers設置方法

(9)JMS provider 必須實現PTP,pub/sub兩種消息通訊模型

(10) 修正了在使用MapMessage SetBytes方法時name為null的不一致異常表現。

        其它的小改進,比方說:訂閱名字的128個字符限製,可選擇的共享持久化訂閱ClientId,Message新增 getBody方法,JMSExpiratoin的定義更加清晰等大家可以查閱手冊。

        通過上麵的概述,我們發現,2.0規範仍舊沒有在Load balance/Fault-tolerance,Administration,Securiy,Wire Protocol,Message Store等方麵給予規範性指導。這些也成為開源MOM在這些領域百花齊放的一個重要原因,比方說ZeroMQ在Wire Protocol層麵的努力,AMQ在Message Store方麵的不斷嚐試,Hornet MQ在Load Balance方麵則引入了JGroup。可謂"因為規範,所以簡單。因為開源,所以精彩“。

         有了上麵粗線條的介紹,我們來具體看下規範究竟為我們展示了什麼?

         首先,我們來看下JMS Application的組成:

                                               

       這裏重點說明一下其中的三個組件:

       Non-JMS Clients ,作為JMS clients的一個重要補充,主要使用消息係統的一些Native API做事,比方說在zeroMQ中,如果使用Java版的client(JZMQ),本地可能會有個.o或者.dll的代碼庫,client通過通過調用native API 可以獲得更好的性能(具體可以參見:https://github.com/zeromq/jzmq)。

       Messages,在JMS規範中,定義了5中類型:BytesMessage,MapMessage,ObjectMessage,StreamMessage,TextMessage.

       Administered Object,在JMS規範中,主要指的是預定義的ConnectionFactory,Destination類(一個用來管理Conenction,一個用來統一message-domain中的queue & topic),在JMS 2的幾個核心概念中,也隻有它們是支持並發的,這點請大家注意(JMSContext,JMSProducer,JMSConsumer則不然)。

        Ok,有了這些知識,我們來看看JMS 2是如何簡化API的,上圖看真相:


                                                                                                          JMS 1.x 



                                                                                                               JMS 2.x


       怎麼樣,很清晰吧,雖然不喜歡特性化的JMS命名,沒辦法,老接口還得用,命名隻能這樣將就一下了,難不成,各位親還有其它更好的命名?

       JMSContext雖然從結構上看,統一了Connection& Session,但是其並未暴露獲取它們的API,瞧,封裝的多好?(好在哪,請大家思考)不過大家要明白Connection對象代表了一條到JMS broker的物理鏈接抽象,而Session則代表了單線程的會話(Send or Receive)

       下麵,我們再來看另一個設計細節:JMS message的組成:

       Header:

       Properties(Application-specific properties & Standard properties,Provider-specific properties)

       Application-specific properties &Standard properties:


     Provider-specific properties : 如含有JMS_<vendor_name>屬性名前綴,主要用在provider-native clients當中。

     Message Selector,再來看下這個存在已久的特性,它支持SQL 92語法,可以通過消息頭,消息屬性過濾實際投遞到消費端消息,通過這個定義,我們似乎覺得Message Filter的概念更為貼近它的使用場景,有麼有???

     Message Order,首先來看Order of message receipt,規範上寫的挺清楚的,不解釋

    JMS defines that messages sent by a session to a destination must be received in the order in which they weresent . This defines a partial ordering

constraint on a session’s input messagestream.

   JMS does not define order of message receipt across destinations or across a destination’s messages sent from multiplesessions. This aspect of a

session’s input message stream order istiming-dependent. It is not under application control.

     再來看Order of message sends,這裏麵有幾個影響因子:Message PriorityDelivery mode。一句話概括一下:不保證,JMS provider自己實現

     在這一點上LinkedIn的Kafka通過Partition等有條件地實現了順序消息,不過也從一定程度上犧牲了MOM的可擴展性,吞吐量。

     最後一個主題:Duplicate production of message & Duplicate delivery of message,規範裏的硬性規定其實很直白: 不能投遞已經確認了(acknowledged message)的信息兩次(second copy); 不能夠生產duplicate message,由於session recovery導致的情況除外。哈哈,剩下的就由JMS provider 去實現吧(AT_MOST_ONCE,DUPLICATEDS_OK,ONCE_AND_ONLY_ONCE,任你選的QOS)。

    恩,差不多了,剩下的API層麵的改進,大家就在用的過程中去體會吧。

結束語:

     研究規範,而又不囿於規範。

     後麵會陸續寫一些文章,和大家分享一下自己在MOM方麵的探索,希望你能喜歡~

     最後,保持研究的嚴謹性,附上參考資料,大家有空可以自己閱讀~

附錄:

    在工作中基於JMS 2規範開發了一套編程模型,如下:



參考資料:

1. https://www.oracle.com/technetwork/java/javaee/javaee7-whitepaper-1956203.pdf

2. https://jcp.org/aboutJava/communityprocess/final/jsr343/index.html

最後更新:2017-04-03 15:21:46

  上一篇:go hdu 1850 博弈 入門
  下一篇:go C# 數據庫存儲過程的講解應用