雙機器環境模擬生產級 MQ 分散式部署:
| 項目 | 機器 A (發送端) | 機器 B (接收端) |
|---|---|---|
| 代碼/主機名 | 00000000 | 88888888 |
| IP 位址 | 10.1.1.1 | 10.1.1.2 |
| 隊列管理器 | QM_00000000 | QM_88888888 |
| 本地隊列 | LQ_00000000 | LQ_88888888 |
| 傳輸隊列 | XQ_88888888 | XQ_00000000 |
| 遠程隊列定義 | RQ_88888888 → LQ_88888888@QM_88888888 | RQ_00000000 → LQ_00000000@QM_00000000 |
| 發送方通道 | 00000000.88888888 (TCP 10.1.1.2:1414) | 88888888.00000000 (TCP 10.1.1.1:1414) |
| 接收方通道 | 88888888.00000000 | 00000000.88888888 |
| 伺服器連接通道 | DC.SVRCONN (客戶端連接用) | |
QM_00000000,預設設定LQ_00000000XQ_88888888(用法選「傳輸」)RQ_88888888:
LQ_88888888QM_88888888XQ_8888888800000000.88888888:
10.1.1.2(1414)XQ_8888888888888888.00000000(預設)DC.SVRCONN(預設)隊列管理器 QM_88888888、本地隊列 LQ_88888888、傳輸隊列 XQ_00000000、遠程隊列 RQ_00000000 指向機器 A、發送方通道 88888888.00000000 連接 10.1.1.1(1414)、接收方通道 00000000.88888888、伺服器連接通道 DC.SVRCONN。
# 兩台機器分別啟動發送方通道
# 狀態應顯示 "RUNNING" (正在運行)
# 若為 RETRYING/STOPPED,檢查:
# 1. 防火牆 1414 埠
# 2. 通道名稱雙向完全一致 (大小寫敏感)
# 3. 傳輸隊列名稱拼寫
# 4. 遠程隊列管理器名稱拼寫
import java.io.IOException;
import java.util.Hashtable;
import com.ibm.mq.*;
public class MQTest {
private static String qmName = "QM_00000000";
private static String qName = "RQ_88888888"; // 遠程隊列定義
private static MQQueueManager qMgr;
private static Hashtable props = new Hashtable();
public static void main(String[] args) {
try {
// 連接屬性配置
props.put("hostname", "10.1.1.1"); // 本機 IP (客戶端連接本機 QM)
props.put("port", new Integer(1414));
props.put("channel", "DC.SVRCONN"); // 伺服器連接通道
props.put("CCSID", new Integer(1381)); // 字符集:GB18030/中文
props.put("transport", "MQSeries"); // 傳輸類型
// 建立連接
qMgr = new MQQueueManager(qmName, props);
// 開啟遠程隊列 (OUTPUT 權限 = 16)
int openOptions = MQConstants.MQOO_OUTPUT;
MQQueue remoteQ = qMgr.accessQueue(qName, openOptions);
// 建立訊息
MQMessage putMessage = new MQMessage();
putMessage.writeUTF("Test Message from Machine A");
// 發送選項
MQPutMessageOptions pmo = new MQPutMessageOptions();
// 放入隊列
remoteQ.put(putMessage, pmo);
System.out.println("Message sent to Remote Queue successfully");
// 清理資源
remoteQ.close();
qMgr.disconnect();
} catch (MQException ex) {
System.err.println("MQ Error: CC=" + ex.completionCode + ", RC=" + ex.reasonCode);
// 常見代碼:2035 (權限)、2058 (QM 名稱錯誤)、2059 (連接失敗)
} catch (IOException ex) {
System.err.println("Message buffer error: " + ex);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
LQ_88888888 本地隊列MsgId、CorrelId、PutDate/PutTime 正常即成功MQMessage msg = new MQMessage();
msg.persistence = MQConstants.MQPER_PERSISTENT; // 預設即持久化
// 需確保隊列定義 DEFPSIST(YES)
DEADQ(QM_DLQ)SSLCIPH、配置金鑰庫| 參數 | 建議值 | 說明 |
|---|---|---|
| BATCHSZ | 50-100 | 通道批次大小,減少網路往返 |
| BATCHLIM | 1000 KB | 批次位元組限制 |
| HBINT | 300 | 心跳間隔(秒),檢測斷連 |
| MAXMSGL | 4MB-100MB | 最大訊息長度,視業務而定 |
| NPMSPEED | FAST | 非持久訊息快速模式 |
| 現象 | 可能原因 | 排查步驟 |
|---|---|---|
| 通道狀態 RETRYING | 網路不通/防火牆/通道名不符 | ping/telnet 1414、核對通道名大小寫、檢查錯誤日誌 AMQERR*.LOG |
| MQException 2035 | 權限不足 | 檢查通道 MCAUSER、CHLAUTH、用戶是否在 mqm 群組 |
| 訊息發送成功但接收端無訊息 | 遠程隊列定義錯誤/傳輸隊列未啟用 | 檢查 RQ 定義的 RQMNAME、XMITQ、XQ 狀態、XQ 深度 |
| 中文亂碼 | CCSID 不匹配 | 雙端統一 CCSID 1381 (GB18030) 或 1208 (UTF-8) |
WebSphere MQ 分散式傳輸的核心在於「名稱精確對稱」:通道名雙向一致、隊列管理器名稱精確匹配、傳輸隊列與遠程隊列定義形成閉環。本文提供從基礎設施配置、Java 客戶端測試、驗證方法到生產級強化的完整鏈路。掌握此模式,即可構建高可靠、高效能、安全合規的企業級訊息總線基礎設施。