Java消息服務

Java消息服務（Java Message Service，JMS）應用程序接口是一個Java平臺中關於面向消息中間件（MOM）的API，用於在兩個應用程序之間，或分佈式系統中發送消息，進行異步通信。Java消息服務是一個與具體平臺無關的API，絕大多數MOM提供商都對JMS提供支持。
Java消息服務的規範包括兩種消息模式，點對點和發佈者／訂閱者。許多提供商支持這一通用框架因此，程序員可以在他們的分佈式軟件中實現面向消息的操作，這些操作將具有不同面向消息中間件產品的可移植性。
Java消息服務支持同步和異步的消息處理，在某些場景下，同步消息是必要的；在其他場景下，異步消息比同步消息操作更加便利。
Java消息服務支持面向事件的方法接收消息，事件驅動的程序設計現在被廣泛認為是一種富有成效的程序設計範例，程序員們都相當熟悉。
在應用系統開發時，Java消息服務可以推遲選擇面對消息中間件產品，也可以在不同的面對消息中間件切換。

**歷史**
Java消息服務是一個在 Java標準化組織（JCP）內開發的標準（代號JSR 914）。2001年6月25日，Java消息服務發佈JMS 1.0.2b，2002年3月18日Java消息服務發佈 1.1，統一了消息域。

**體系架構**

**JMS元素**
JMS由以下元素組成。
 JMS提供者
 連接面向消息中間件的，JMS接口的一個實現。提供者可以是Java平臺的JMS實現，也可以是非Java平臺的面向消息中間件的適配器。
 JMS客戶
 生產或消費消息的基於Java的應用程序或對象。
 JMS生產者
 創建併發送消息的JMS客戶。
 JMS消費者
 接收消息的JMS客戶。
 JMS消息
 包括可以在JMS客戶之間傳遞的數據的對象
 JMS隊列
 一個容納那些被髮送的等待閱讀的消息的區域。隊列暗示，這些消息將按照順序發送。一旦一個消息被閱讀，該消息將被從隊列中移走。
 JMS主題
 一種支持發送消息給多個訂閱者的機制。

**JMS模型**
Java消息服務應用程序結構支持兩種模型：- 點對點或隊列模型- 發佈/訂閱模型
在點對點或隊列模型下，一個生產者向一個特定的隊列發佈消息，一個消費者從該隊列中讀取消息。這裡，生產者知道消費者的隊列，並直接將消息發送到消費者的隊列。這種模式被概括為：- 只有一個消費者將獲得消息- 生產者不需要在接收者消費該消息期間處於運行狀態，接收者也同樣不需要在消息發送時處於運行狀態。- 每一個成功處理的消息都由接收者簽收
發佈者／訂閱者模型支持向一個特定的消息主題發佈消息。0或多個訂閱者可能對接收來自特定消息主題的消息感興趣。在這種模型下，發佈者和訂閱者彼此不知道對方。這種模式好比是匿名公告板。這種模式被概括為：- 多個消費者可以獲得消息 - 在發佈者和訂閱者之間存在時間依賴性。發佈者需要建立一個訂閱（subscription），以便客戶能夠訂閱。訂閱者必須保持持續的活動狀態以接收消息，除非訂閱者建立了持久的訂閱。在那種情況下，在訂閱者未連接時發佈的消息將在訂閱者重新連接時重新發布。
使用Java語言，JMS提供了將應用與提供數據的傳輸層相分離的方式。同一組Java類可以通過JNDI中關於提供者的信息，連接不同的JMS提供者。這一組類首先使用一個連接工廠以連接到隊列或主題，然後發送或發佈消息。在接收端，客戶接收或訂閱這些消息。

**JMS應用程序接口**
Java消息服務的API在javax/jms包中提供。

**ConnectionFactory 接口（連接工廠）**
用戶用來創建到JMS提供者的連接的被管對象。JMS客戶通過可移植的接口訪問連接，這樣當下層的實現改變時，代碼不需要進行修改。 管理員在JNDI名字空間中配置連接工廠，這樣，JMS客戶才能夠查找到它們。根據消息類型的不同，用戶將使用隊列連接工廠，或者主題連接工廠。

**Connection 接口（連接）**
連接代表了應用程序和消息服務器之間的通信鏈路。在獲得了連接工廠後，就可以創建一個與JMS提供者的連接。根據不同的連接類型，連接允許用戶創建會話，以發送和接收隊列和主題到目標。

**Destination 接口（目標）**
目標是一個包裝了消息目標標識符的被管對象，消息目標是指消息發佈和接收的地點，或者是隊列，或者是主題。JMS管理員創建這些對象，然後用戶通過JNDI發現它們。和連接工廠一樣，管理員可以創建兩種類型的目標，點對點模型的隊列，以及發佈者／訂閱者模型的主題。

**MessageConsumer 接口（消息消費者）**
由會話創建的對象，用於接收發送到目標的消息。消費者可以同步地（阻塞模式），或異步（非阻塞）接收隊列和主題類型的消息。

**MessageProducer 接口（消息生產者）**
由會話創建的對象，用於發送消息到目標。用戶可以創建某個目標的發送者，也可以創建一個通用的發送者，在發送消息時指定目標。

**Message 接口（消息）**
是在消費者和生產者之間傳送的對象，也就是說從一個應用程序創送到另一個應用程序。一個消息有三個主要部分：
# 消息頭（必須）：包含用於識別和為消息尋找路由的操作設置。
# 一組消息屬性（可選）：包含額外的屬性，支持其他提供者和用戶的兼容。可以創建定製的字段和過濾器（消息選擇器）。
# 一個消息體（可選）：允許用戶創建五種類型的消息（文本消息，映射消息，字節消息，流消息和對象消息）。
消息接口非常靈活，並提供了許多方式來定製消息的內容。

**Session 接口（會話）**
表示一個單線程的上下文，用於發送和接收消息。由於會話是單線程的，所以消息是連續的，就是說消息是按照發送的順序一個一個接收的。會話的好處是它支持事務。如果用戶選擇了事務支持，會話上下文將保存一組消息，直到事務被提交才發送這些消息。在提交事務之前，用戶可以使用回滾操作取消這些消息。一個會話允許用戶創建消息生產者來發送消息，創建消息消費者來接收消息。

**JMS提供者實現**
要使用Java消息服務，你必須要有一個JMS提供者，管理會話和隊列。現在既有開源的提供者也有專有的提供者。
開源的提供者包括：- Kafka- Apache ActiveMQ- JBoss 社區所研發的 HornetQ-  Joram date=20090323071620 - Coridan的 MantaRay date=20201125230543  -  The OpenJMS Group date=20201220050848 的OpenJMS
專有的提供者包括：- BEA的BEA WebLogic Server JMS- TIBCO軟件公司的 EMS-  GigaSpaces Technologies date=20210126160246 的GigaSpaces-  Softwired 2006的iBus- IONA Technologies的IONA JMS-  SeeBeyond date=20081202040210 的IQManager（2005年8月被Sun Microsystems併購）- webMethods的JMS+ - http://www.webmethods.com date=20081120212119 -  my-channels date=20191024093707 的Nirvana- Sonic Software的SonicMQ- IBM的WebSphere MQ
一個詳盡的JMS提供者對比矩陣可以在 這裡 date=20080820014521 看到。
如果你計劃在一個服務器集群中運行你的程序，你需要檢查提供者是否實現了對負載均衡和故障恢復的支持。

**參見**
J2EE連接器架構
*J2EE
*JDBC
*面向消息中間件
*企業應用集成

**外部鏈接**
  Sun's JMS Overview date=20090911054525 -  JSR 914 date=20201031231550  (JMS 1.0 and 1.1)-  GigaSpaces Technologies JavaSpaces approach to JMS
分類:Java企業平臺