傳統認知認爲消息中間件僅適用於小數據量、低頻異構系統集成。但隨著 Java/.NET 將分布式能力內化為編程模型一部分,JMS 已具備高可用、容錯、高性能特質。本文記錄團隊如何用 JMS (IBM MQSeries) 替代 FTP/SCP 定制方案,解決全國呼叫中心多媒體文件(50K-500K)可靠歸檔難題。
客戶現有系統:VPN + 定制代碼,性能不可靠、維護成本高。非 JMS 方案(FTP/SCP)缺陷:
JMS 原生提供持久化、事務、集群、安全、JNDI 集中配置等企業級特性,經測試 1MB 消息負載經適當調優不影響吞吐,果斷選型。

BytesMessage 發送至 JMS Server,收到 ACK 後刪除本地文件。FileListener 並發消費隊列,存檔歸檔。JMS 保證每條消息僅被消費一次。封裝廠商特有邏輯(工廠查找、連接創建、屬性設置)至 JmsProvider 及子類 MQSeriesProvider。利用 JNDI/LDAP 外部化配置(連接工廠、隊列名),代碼近零硬編碼。
// 通用連接創建
public QueueConnection createConnection() throws JMSException {
return getConnectionFactory().createQueueConnection(getUserName(), getPassword());
}
// MQSeries 綁定模式覆寫:無需傳用戶名密碼
public QueueConnection createConnection() throws JMSException {
return getConnectionFactory().createQueueConnection();
}
DeliveryMode.PERSISTENT 確保消息落盤。ConnectionPool 複用連接,Poller 線程取連接 → 構建消息 → 發送 → 歸還連接。listen.call() 驅動後續流程。
public void onMessage(Message message) {
BytesMessage bm = (BytesMessage) message;
try (OutputStream out = new BufferedOutputStream(new FileOutputStream(getFilenameFor(message)))) {
byte[] buf = new byte[BUFFER_SIZE];
int len;
while ((len = bm.readBytes(buf)) != -1) out.write(buf, 0, len);
}
}
FileListener 並發,JMS 保證無重複消費。main 方法無限 sleep 防止 JVM 過早退出(守護線程導致)。JMSAdmin.bat 註冊 JMS 專用隊列/工廠對象(非標準 MQ 對象)。六周上線,完全替換舊系統,超越所有基準指標,修復歷史數據錯誤。證明 JMS 不僅勝任輕量級消息,更能承擔大規模、任務關鍵型數據傳輸。後續擴展:消息壓縮、斷點續傳、集群代理、安全加固、審計日誌、管理控制台,均得益於 JMS 開放模型與健壯架構。