IBMMQ的使用总结
最近公司用到IBMMQ来进行报文收发。在此作一个小的总结。
使用的是Sender–Receiver模式也就是网络中有2台安装了MQ的机器,实现互相之间的报文收发一对一的通信。
一丶首先关于版本的的问题。
可以去IBM官网下载,https://www.ibm.com/developerworks/cn/downloads/ws/wmq/, 建议下载advance版本,没有日期限制,只是减少了部分后端支持,目前最新的是9.几的版本,windows10可以正常使用,我在自己电脑上安装的这个版本测试的.但在服务器上我安装的8.0的wbsphere版本,webserver2012R2 系统安装最新的版本没法建立队列管理器。
二、mq通信搭建
首先需要2台同一网内的机器。(win10系统)安装好mq。
A机器:ip:192.168.1.133
B机器:ip:192.168.1.110
接下来创建mq对象
1.A机器上打开mq资源管理器,右击队列管理器,新建队列管理器 QM_00000000,需要建死信队列就把名字加进去。其余的默认设置即可,监听端口如果新建第一个,默认的是1414。
2.在队列管理器QM_00000000中右击队列建立本地队列LQ_00000000
3.建立传输队列XQ_88888888,还是新建本地队列,用户改为传输就行。
4.创建远程队列,名称为RQ_88888888,远程队列LQ_88888888,远程队列管理器QM_88888888,传输队列XQ_88888888。
5.右击通道,创建发送方通道名为00000000.88888888,对应B机器的接收方通道名,连接名称192.168.1.110(1414),传输队列XQ_88888888.
6.创建接收方方通道名为88888888.00000000对应B机器的接受方通道名称。其余默认设置。
7.创建服务器连接通道,名为DC.SVRCONN,用于后面的java程序测试,其余默认设置。
B.服务器按此步骤创建。
1.新建队列管理器 QM_88888888,需要建死信队列就把名字加进去。其余的默认设置即可,监听端口如果新建第一个,默认的是1414。
2.在队列管理器QM_88888888中右击队列建立本地队列LQ_88888888。
3.建立传输队列XQ_00000000,还是新建本地队列,用户改为传输就行。
4.创建远程队列,名称为RQ_00000000,远程队列LQ_00000000,远程队列管理器QM_00000000,传输队列XQ_00000000。
5.右击通道,创建发送方通道名为88888888.00000000,对应A机器的接收方通道名,连接名称192.168.1.133(1414),传输队列XQ_00000000
6.创建接收方方通道名为00000000。88888888对应B机器的接受方通道名称。其余默认设置。
三、测试2台服务器是否已经连接。
以A服务器为例:
1.查看发送方通道是否正在运行。如果显示运行状态表示已经连接上。然后在远程队列中右击放入测试信息。到B服务器本地队列查看是否接受到信息,如果接受到了说明A连接B了。(截图已A服务器为例)
2.如果是正在重试的状态如下图:
说明B机器端口号没通。此时telnet b机器1414是不通的,这时需要点击侦听器查看侦听器是否正在运行,如果没有运行,是没法连接B服务器的。如下图:
此时右击启动,然后重新在启动发送方通道看是否可以运行,当时我是因为这个问题没法连接。
四、如果通道都是正常运行状态,接下来再通过java程序来进行消息的收发。(A机器为例)。
1.建立好项目之后,需要一个mq的jar包,我是在阿里仓库下的一个总的jar包。
其他下载
链接:https://pan.baidu.com/s/1gD24EKYjEv2ZrSqfd2MyDA
提取码:4oq8
2.程序代码。
package IBMMQ;
import java.io.IOException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import com.ibm.mq.MQC;
import com.ibm.mq.MQEnvironment;
import com.ibm.mq.MQException;
import com.ibm.mq.MQGetMessageOptions;
import com.ibm.mq.MQMessage;
import com.ibm.mq.MQPutMessageOptions;
import com.ibm.mq.MQQueue;
import com.ibm.mq.MQQueueManager;
public class IBMMQUtils {
private static MQQueueManager qMgr;// 队列管理器
private static MQQueue queue = null;// 队列
private static int CCSID = 1381;// 编码格式代号,1381指的是utf-8(与自己的编码环境一致)
private static String queueMgr = "QM_00000000";// 队列管理器名称
private static String localQueueString = "LQ_00000000";// 本地队列名称
private static String remoteQueueString = "RQ_88888888";// 远程队列名称
private static int sdOpenOptions = 16;// 获取队列的参数,一般第一个参数是【本地队列】的时候就填49,【远程队列】就填16
private static int reOpenOptions = 49;
public static void connect() throws MQException {
MQEnvironment.hostname = "192.168.1.133";
MQEnvironment.channel = "DC.SVRCONN";
MQEnvironment.port = 1414;
MQEnvironment.CCSID = CCSID;
MQEnvironment.userID = "MUSR_MQADMIN";// MQ中拥有权限的用户名
MQEnvironment.password = "123456"; // 用户名对应的密码
qMgr = new MQQueueManager(queueMgr);
}
public static void sendMsg(String msgStr) {
try {
queue = qMgr.accessQueue(remoteQueueString, sdOpenOptions, null,null, null);
MQMessage msg = new MQMessage();// 要写入队列的消息
msgConfig(msg, msgStr);
MQPutMessageOptions pmo = new MQPutMessageOptions();
queue.put(msg, pmo);// 将消息放入队列
System.out.println("消息已放入远程队列!");
System.out.println("===========================");
} catch (Exception e) {
e.printStackTrace();
} finally {
if (queue != null) {
try {
queue.close();
} catch (MQException e) {
e.printStackTrace();
}
}
}
}
public static void receiveMsg() {
try {
queue = qMgr.accessQueue(localQueueString, reOpenOptions, null,null, null);
int depth = queue.getCurrentDepth();
System.out.println("本地队列当前的深度为:" + queue.getCurrentDepth());
System.out.println("===========================");
while (depth-- > 0) {//将队列的消息读取出来
MQMessage msg = new MQMessage();//要读的队列的消息
MQGetMessageOptions gmo = new MQGetMessageOptions();
queue.get(msg, gmo);
System.out.println("消息的大小为:" + msg.getDataLength());
System.out.println("消息的内容:\n"+ msg.readStringOfByteLength(msg.getDataLength()));
System.out.println("---------------------------");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (queue != null) {
try {
queue.close();
} catch (MQException e) {
e.printStackTrace();
}
}
}
//return revMap;
}
public static void msgConfig(MQMessage msg, String msgStr)
throws IOException {
msg.format = MQC.MQFMT_STRING;
msg.characterSet = CCSID;
msg.encoding = CCSID;
msg.writeString(msgStr);// 将消息写入消息对象中
msg.expiry = -1; // 设置消息用不过期
}
public static void main(String[] args) throws MQException {
connect();
Date date = new Date();
sendMsg("你好"+date);
receiveMsg();
}
}
输出结果:
因为本地队列没有信息。所以现实深度为0.消息放入远程队列后可以查看到自己传输队列的深度变为1了(如图2)。然后在B服务器本地队列中可以查看到A服务器刚刚发送的信息。
图1:
图2:
参考博客1. https://blog.csdn.net/lvshaorong/article/details/77188538
2.https://blog.csdn.net/qq_17616169/article/details/54633005