依赖:
* mq-x
* connector-x
* jmqi-x
* commonservices-x
* headers-x
* mqjms-x
public static void send(String qName, String msg) throws MQException, IOException {
Hashtable properties = new Hashtable();
properties.put(MQConstants.CONNECT_OPTIONS_PROPERTY, MQConstants.MQCNO_RECONNECT);
properties.put(MQConstants.HOST_NAME_PROPERTY, connectionName);
properties.put(MQConstants.PORT_PROPERTY, port);
properties.put(MQConstants.CHANNEL_PROPERTY, channel);
properties.put(MQConstants.CCSID_PROPERTY, ccsid);
MQQueueManager queueMgr = new MQQueueManager(qManager, properties);
MQQueue queue = queueMgr.accessQueue(qName, openOptions, null, null, null);
MQMessage outMsg = new MQMessage();
outMsg.write(msg.getBytes("UTF-8"));
queue.put(outMsg, new MQPutMessageOptions());
queueMgr.commit();
queue.close();
queueMgr.disConnect();
}
缺省情况下,每次new MQQueueManger()调用都意味着应用程序与队列管理器多了一条连接,在MQ Clinet/Server 结构中表现为多了一条TCP/IP连接。每次MQQueueManger.disconnect()时这条连接断开,即为TCP/IP连接断开。例如,在同一个线程中,如果反复连接再断开MQ Connection,在MQ Clinet/Server 结构中表现为反复连接再断开TCP/IP连接,在系统中可以用netstat命令看到一些痕迹,即每次连接断开后的TIME_WAIT状态。
例:
for(int i = 0; i < 10; i++){
qmgr = new MQQueueManager(sMQname);
...
qmgr.disconnect();
}
如果使用了连接池 Connection Pool,在MQQueueManger.disconnect()时MQ连接并没真正断开,只是交回连接池,在下一次new MQQueueManager时重用。
MQPoolToken token = MQEnvironment.addConnectionPoolToken ();
for (int i = 0; i < 10; i ++)
{
qmgr = new MQQueueManager (sQMName);
...
qmgr.disconnect ();
}
MQEnvironment.removeConnectionPoolToken (token);
在并发线程的情况下,如果线程之间的new MQQueueManager()是串行的,则连接可以跨线程共享;
如果是并发的,则可以为每个线程创建一个连接复用环境,连接在此线程的串行new MQQueueManager()操作之间是复用的。
for (int i = 0; i < 3; i ++)
{
thread = new MQConnectionPoolThread (sQMName);
thread.start ();
}
class MQConnectionPoolThread extends Thread
{
...
public void run ()
{
token = MQEnvironment.addConnectionPoolToken ();
for (int i = 0; i < 5; i ++)
{
try
{
***synchronized (getClass ())***
{
qmgr = new MQQueueManager (sQMName);
sleep (1000);
qmgr.disconnect ();
}
}
}
MQEnvironment.removeConnectionPoolToken (token);
}
}
MQEnvironment中缺省Connection Pool最多可以保持10无用连接,每条最长保持5min。
例如:同时有 15 个并发 new MQQueueManager (),会有 15 条有用连接。
其中有 12 个很快就 MQQueueManager.disconnect () 了,这时应用会有 3 条有用连接,10条无用连接,另有 2 条连接断开。
可以用 MQEnvironment.setDefaultConnectionManager (MQConnectionManager) 将自己创建的 Connection Pool 设置成缺省的 Connection Pool。
MQConnectionManager 是一个 private interface,在 MQ Java Base 中只有一个类实现了这个界面:MQSimpleConnectionManager
MQQueueManager 的构造函数有一款为 : public MQQueueManager (String
queueManagerName,MQConnectionManager cxManager) 表示创建的连接加入 cxManager中的 Connection Pool,由 cxManager 进行管理 (最多无用连接、超时等等)。
依赖:
* jms-api-x
* dhbcore-x
<bean id="mqQueueConnectionFactory" class="com.ibm.mq.jms.MQQueueConnectionFactory">
bean>
<bean id="cachingConnectionFactory" class="org.springframework.jms.connection.CachingConnectionFactory">
<property name="targetConnectionFactory" ref="mqQueueConnectionFactory" />
<property name="sessionCacheSize" value="x" />
bean>
<bean id="senderQueue" class="com.ibm.mq.jms.MQQueue">
<property name="baseQueueName" value="xx"/>
<property name="baseQueueManagerName" value="xx"/>
bean>
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="cachingConnectionFactory"/>
<property name="pubSubDomain" value="false"/>
bean>
Return code=2082 MQRC_UNKNOWN_ALIAS_BASE_Q opening a queue in the cluster.
just leave the baseQueueManagerName blank
reference
发送时,当有多个queue时,建议使用
jmsTemplate.convertAndSend(QueueName, msg);
<Resource name="jms/XXXMQ" auth="Container"
type="com.ibm.mq.jms.MQQueueConnectionFactory" factory="com.ibm.mq.jms.MQQueueConnectionFactoryFactory"
description=""
HOST="xxx" PORT="xxx" CHAN="xxx" TRAN="1"
CCSID="xxx" QMGR="xxx" />
<Resource name="jms/SENDQUEUE" auth="Container"
type="com.ibm.mq.jms.MQQueue" factory="com.ibm.mq.jms.MQQueueFactory"
description="ACTIVITY message input queue" QU="CMF_INPUTQ" CCSID="1208" />
<jee:jndi-lookup id="mqConnectionFactory" jndi-name="jms/XXXMQ" resource-ref="true" />
<bean id="jmsTemplate" class="org.springframework.jms.core.JmsTemplate">
<property name="connectionFactory" ref="mqConnectionFactory"/>
<property name="defaultDestination" ref="SENDQUEUE"/>
<property name="pubSubDomain" value="false"/>
bean>
@AutoWired
JmsTemplate jmsTemplate;
...
jmsTemplate.convertAndSend(msg);
jmsTemplate.convertAndSend(destinationName, msg);
...
ps:省略了MQ Interface上Queue和其他的配置