首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

基於 GlassFish 實現 JMS 消息傳遞與 MDB 異步處理完整指南

     編輯:Java 相關知識

Java 消息服務(JMS)構建鬆耦合、可擴展的分布式系統。本文系統介紹 JMS 核心模型、消息類型、消息驅動 Bean(MDB)異步處理機制,並以 GlassFish 為平台,通過一個「Web 訪問追蹤器」實戰案例,演示從 Servlet 過濾器捕獲請求、JMS 異步發送、MDB 消費持久化到 JAXB XML 存儲的完整鏈路,包含資源配置、部署描述符、測試驗證全流程。

一、JMS 核心概念與兩大傳遞模式

1. 點對點(PTP,Queue)

  • 消息發送到隊列,唯一消費者接收處理。
  • 發送者與接收者無時間依賴,消息持久化存儲直到被消費。
  • 適用於任務分發、命令執行等單消費者場景。

2. 發布-訂閱(Pub/Sub,Topic)

  • 消息發布到主題,多個訂閱者均可收到。
  • 存在時間依賴:訂閱者需處於活躍狀態才能收到消息。
  • 支持持久訂閱:訂閱者離線時消息由 JMS Provider 保留,重新上線時接收。
  • 適用於事件通知、廣播等多消費者場景。

3. 五種標準消息類型

類型描述
TextMessage字符串文本或 java.lang.String
ObjectMessage可序列化 Java 對象(Serializable)
BytesMessage字節流
MapMessage鍵值對集合
StreamMessage基本類型數據流

二、消息驅動 Bean(MDB)異步處理核心

  • 實現 javax.jms.MessageListener 接口,核心方法 onMessage(Message msg)。
  • 容器負責生命周期管理、事務邊界、併發控制,MDB 無狀態、事務感知。
  • 客戶端不直接調用 MDB,而是發送消息到 MDB 監聽的目的地(Queue/Topic)。
  • EJB 3.0 使用 @MessageDriven(mappedName="queueName") 注解聲明,@Resource 注入 MessageDrivenContext。

三、GlassFish JMS 資源配置實戰

GlassFish 整合 Sun Java System Message Queue,提供開箱即用的 JMS Provider。需配置兩類資源:

1. 連接工廠

  • ConnectionFactory:PTP 與 Pub/Sub 通用。
  • QueueConnectionFactory:專用於 PTP。
  • TopicConnectionFactory:專用於 Pub/Sub。
  • 支持連接池:初始/最小/最大連接數、空閒超時、重新調整量等參數可在管理控制台或 asadmin 配置。

2. 目的地資源

  • Queue:PTP 目的地。
  • Topic:Pub/Sub 目的地。

3. 管理控制台配置步驟(以 Queue 為例)

  1. 登錄控制台 → Resources → JMS Resources → Connection Factories → New。
  2. JNDI Name: webTrackerConnFactory,Resource Type: javax.jms.QueueConnectionFactory。
  3. Resources → JMS Resources → Destination Resources → New。
  4. JNDI Name: webTrackerQueue,Physical Destination: webTrackerQueue,Resource Type: javax.jms.Queue。

四、實戰案例:Web Access Tracker 異步日誌收集

1. 架構流程

  1. Servlet Filter 攔截請求,提取 URL、IP、User-Agent、響應時間等數據,封裝為 DTO。
  2. JMS 客戶端(注入 QueueConnectionFactory 和 Queue)創建連接、會話、生產者,發送 ObjectMessage 到隊列。
  3. MDB 監聽隊列,onMessage() 接收消息,轉換為 DTO,持久化到 XML 文件。
  4. JAXB 實現 XML 解編/編組,讀寫 webAccessLog.xml。
  5. JSF 前端展示訪問統計報表。

2. 關鍵代碼片段

Servlet Filter 發送消息:

@Resource(name="connFactory", mappedName="webTrackerConnFactory")
private QueueConnectionFactory qFactory;
@Resource(name="jmsQueue", mappedName="webTrackerQueue")
private Queue queue;

public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
    // ... 提取請求數據到 RequestData DTO ...
    QueueConnection qConn = qFactory.createConnection();
    Session session = qConn.createSession(false, Session.AUTO_ACKNOWLEDGE);
    ObjectMessage msg = session.createObjectMessage();
    msg.setObject(data);
    session.createProducer(queue).send(msg);
    // ... 關閉資源 ...
    chain.doFilter(req, res);
}

MDB 接收並持久化:

@MessageDriven(mappedName = "webTrackerQueue")
public class WebTrackerEJB implements MessageListener {
    @Resource private MessageDrivenContext mdbContext;

    public void onMessage(Message message) {
        if (message instanceof ObjectMessage) {
            RequestData data = (RequestData) ((ObjectMessage) message).getObject();
            persistToXml(data); // 使用 JAXB 寫入 XML
        }
    }
}

JAXB XML 讀寫:

// 解編
JAXBContext jc = JAXBContext.newInstance("demo.webtracker.xmlgen");
Unmarshaller u = jc.createUnmarshaller();
WebAccess access = (WebAccess) u.unmarshal(new FileInputStream(xmlPath)).getValue();

// 編組
Marshaller m = jc.createMarshaller();
m.marshal(accessData, new File(xmlPath));

3. 部署描述符(輔助注解配置)

ejb-jar.xml 聲明 MDB、事務屬性;sun-ejb-jar.xml 綁定 JNDI 名稱與連接工廠。若已使用注解,可省略。

五、部署與測試驗證

  1. 打包為 EAR(Web 模塊 + EJB 模塊)。
  2. GlassFish 控制台部署 EAR,設置系統屬性 -Dxmlstore.path=/path/to/webAccessLog.xml。
  3. 訪問 https://host:port/webTracker,瀏覽頁面產生請求。
  4. 點擊「Web Access Info」查看統計報表,驗證異步持久化效果。

六、總結與最佳實踐

  • JMS + MDB 實現高吞吐、鬆耦合、可靠的異步處理,優於同步 RPC。
  • GlassFish 內建 JMS Provider,配置簡單,生產環境可直接使用。
  • 生產環境建議:啟用持久化消息、配置死信隊列、監控隊列積壓、合理設置連接池參數。
  • JAXB 適合中小型 XML 數據存儲,大數據量場景建議遷移到數據庫或 NoSQL。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved