一.配置集群
本文描述在MQ Exporler 配置集群的方法
1.新建3个队列管理器,分别为QM1,QM2,QM3(这三个队列管理器可以在不同的主机,不同环境上)
2.在MQ Exporler 上添加这三个队列管理器,确保连接通畅
3.在“队列管理器集群”中新建集群,命名为“CLUSTER_TEST”,默认会选择两个队列管理器进入完整存储库中,我们选择QM1,QM2
4.选择好进入完整存储库的队列管理器后,会逐个要求输入“集群接收方通道名称”以及“集群接收方通道连接名称”;其中“集群接收方通道名称”是指向自己的接收通道如TO.QM1,请注意确保这个名称的唯一性,假如QM1已经存在于其他集群中,并且通道名为TO.QM1,那么现在集群中就不能再用TO.QM1了。“集群接收方通道连接名称”是指向QM1所在的主机,它有格式要求的,这个命名不能随便命名,必须是 IP(PORT)格式的,比如我的QM1在远程机上,那么这个名称就如:192.168.178.129(1415)。
配置完成这两个通道就完成了集群的配置,点击完成后会分别在QM1,QM2上建立两个通道,一个是发送方通道,一个是接收方通道,这两个通道是相互对应的,即QM1上的发送方通道TO.QM2对应QM2上的接收方通道TO.QM2;QM1上的接收方通道TO.QM1,对应QM2上的发送方通道TO.QM1
5.分别进入QM1,QM2的通道,将以上配置的发送方通道启动,对应的接收方通道会自动启动,启动后通道的状态都是“正在运行”,则说明集群已经建立成功。
6.如果需要继续往集群中加入队列管理器,可以右键点击集群名称,选择将队列管理器添加到集群中,我们这里将QM3加入集群
注意在接下去的步骤中有一个选择“完整存储库”或“部分存储库”,这里选择部分就可以了,详细的说明请看关于存储库的介绍。
二.测试集群队列
集群队列:宿主队列管理器拥有对该队列的本地定义,让它在集群中共享,并且可以往该队列中发送和接收消息;而群集中的其他成员也可以看到这个队列,
但是只能往该队列发送消息,不能从中接收数据。
1.在QM2,QM3分别建立同名的本地队列 RECEIVER.IN ,并设置其在集群CLUSTER_TEST中共享,这样在集群中任何一个队列管理器内都可以见到这两个队列。
任何一个队列管理器对可以往这两个队列管理器中放入消息,更特别的是,如果在QM1中往这RECEIVER.IN放入消息,还可以实现负载均衡,比如有5条消息进入,MQ会自动采取策略将这5条消息分别放入QM2,QM3的RECEIVER.IN中,一个得到2条,另一个得到3条。可以用一下的应该程序测试
往队列RECEIVER.IN放入消息:
package com.watson.mq;
import java.io.IOException;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.MQConstants;
public class MQSender {
public static void main(String[] args) {
System.out.println("Starting Sender");
MQQueueManager queueManager = null;
MQQueue q = null;
try {
// connect to default queue manager specified as first program
// argument from the command line
/*
* MQEnvironment设置MQ环境的静态属性,在MQQueueManager被调用构造之前就需要设置好相关的属性,
* 当MQQueueManager被构造的时候就自动能将相关参数设置进去。
如果队列管理器在远程主机上,则需要配置MQEnvironment属性,如果队列管理器跟应用程序在同一台主机上,就不需要配置
*/
/*MQEnvironment.hostname = "192.168.178.129";
MQEnvironment.port = 2414;
MQEnvironment.channel = "CH_QM1";*/
queueManager = new MQQueueManager("IB9QMGR");
// Connect to the receiver's cluster queue
// This queue dosn't need to be defined
// as a remote queue on the local queue manager
// Rather, it is defined in the cluster repository
// therefore this queue manager knows about it
q = queueManager.accessQueue("RECEIVER.IN", MQConstants.MQOO_OUTPUT
+ MQConstants.MQOO_BIND_NOT_FIXED);
for (int i = 1; i <= 5; i++) {
MQMessage message = new MQMessage();
message.writeString("Test message " + i);
q.put(message);
System.out.println("Put test message " + i);
}
q.close();
queueManager.disconnect();
} catch (MQException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
} finally {
try {
if (q != null && q.isOpen()) {
q.close();
}
if (queueManager != null && queueManager.isConnected()) {
queueManager.disconnect();
}
} catch (MQException ex) {
ex.printStackTrace();
}
}
}
}
分别从QM2,QM3中取出消息:
package com.watson.mq;
import java.io.IOException;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
import com.ibm.mq.constants.MQConstants;
public class MQReceiver {
public static void main(String[] args) {
System.out.println("Starting Receiver");
try {
// connect to default queue manager specified
// as first program argument from the command line
// MQConnectionManager mcm = new MQConnectionManager();
/*
* MQEnvironment设置MQ环境的静态属性,在MQQueueManager被调用构造之前就需要设置好相关的属性,
* 当MQQueueManager被构造的时候就自动能将相关参数设置进去。
如果队列管理器在远程主机上,则需要配置MQEnvironment属性,如果队列管理器跟应用程序在同一台主机上,就不需要配置
*/
MQEnvironment.hostname = "192.168.178.129";
MQEnvironment.port = 2414;
MQEnvironment.channel = "CH_QM1";
MQQueueManager queueManager = new MQQueueManager("QM1");
MQQueue q = queueManager.accessQueue("RECEIVER.IN",
MQConstants.MQOO_INPUT_SHARED);
MQGetMessageOptions mqGMO = new MQGetMessageOptions();
// wait 10 seconds for a message to appear
mqGMO.waitInterval = 10000;
while (true) {
MQMessage message = new MQMessage();
try {
q.get(message, mqGMO);
System.out.println("Received message: "
+ message.readStringOfByteLength(message
.getDataLength()));
} catch (MQException ex) {
// for any other error than
// "no message available on queue", just exit
if (ex.reasonCode == MQConstants.MQRC_NO_MSG_AVAILABLE) {
break;
}
}
}
if (q != null && q.isOpen()) {
q.close();
}
if (queueManager != null && queueManager.isConnected()) {
queueManager.disconnect();
}
} catch (MQException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} catch (Throwable t) {
t.printStackTrace();
}
}
}