问题描述
在将消息发送到队列的example之后,我们来看看设置连接工厂属性的部分
cf.setStringProperty(WMQConstants.WMQ_HOST_NAME,HOST);
cf.setIntProperty(WMQConstants.WMQ_PORT,PORT);
cf.setStringProperty(WMQConstants.WMQ_CHANNEL,CHANNEL);
cf.setIntProperty(WMQConstants.WMQ_CONNECTION_MODE,WMQConstants.WMQ_CM_CLIENT);
cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER,QMGR);
cf.setStringProperty(WMQConstants.WMQ_APPLICATIONNAME,"JmsPutGet (JMS)");
cf.setBooleanProperty(WMQConstants.USER_AUTHENTICATION_MQCSP,true);
cf.setStringProperty(WMQConstants.USERID,APP_USER);
cf.setStringProperty(WMQConstants.PASSWORD,APP_PASSWORD);
当行 cf.setStringProperty(WMQConstants.WMQ_QUEUE_MANAGER,QMGR);
被删除时,没有任何变化:客户端仍然可以成功发送和接收消息。
在这里设置 WMQConstants.WMQ_QUEUE_MANAGER
属性的目的是什么?
IBM MQ 服务器是基于此 Dockefile 的容器:
FROM ibmcom/mq:9.2.2.0-r1
ENV LICENSE=accept
ENV MQ_DEV=true
ENV MQ_APP_PASSWORD=app-password
ENV MQ_ADMIN_PASSWORD=admin-pwd
ENV MQ_QMGR_NAME=KUPOL_DEV_QM
另外:
在同一个例子中,我们看到了
行
destination = context.createQueue("queue:///" + QUEUE_NAME)
如果前缀 "queue:///"
被删除,它不会破坏应用程序,将行保留为destination = context.createQueue(QUEUE_NAME)
。
我在 Web 上的多个 IBM MQ 示例中看到了类似的内容。
这段代码是怎么回事?是盲目复制粘贴还是有意为之?
解决方法
如果您不设置队列管理器或指定以 *
为前缀的值,您可以连接到在您指定的主机和端口上侦听的任何队列管理器名称。
如果您指定的队列管理器名称没有以 *
为前缀,则它必须与侦听主机和端口的队列管理器的名称相匹配。
您还可以使用 CCDT 来保存连接详细信息,在这种情况下(除了上述几点之外)您指定的队列管理器名称用于在 CCDT 中查找连接详细信息。如果它以 *
为前缀,它将在 CCDT 中查找没有 *
的名称。
除了使用 queue:///
前缀指定队列名称之外,您还可以使用前缀 topic:///
指定主题,我的猜测是 createQueue
默认假设您正在指定一个队列名称。
您的示例代码似乎是 JMS。 IBM MQ 支持多种队列寻址模型。
这三个意思是一样的:
- context.createQueue("MY.QUEUE");
- context.createQueue("queue://MY.QUEUE");
- context.createQueue("queue:///MY.QUEUE");
但是,使用三重斜线,您也可以完全限定 REMOTE 队列
- context.createQueue("queue://QMGRB/MY.OTHER.QUEUE");
这告诉 IBM MQ 将消息发送到 QMgr,并让它将消息传送到“QMGRB”上的远程队列“MY.OTHER.QUEUE”。
注意:IBM MQ 还支持目标选项,因此您可以修改持久性、优先级、字符编码、targetClient 等。这很有用,因此您可以将配置外部化并更改消息模式,而无需更改代码!>
参考:https://www.ibm.com/docs/en/ibm-mq/9.0?topic=applications-creating-destinations-in-jms-application