Websphere MQ & 使用方式(API,spring,JNDI)

来源:互联网 发布:英语长难句分析软件 编辑:程序博客网 时间:2024/06/17 00:13

WMQ

配置

  • HostName
  • Channel
    • 队列管理器之间单向点对点通信连接,消息在通道中单向流动
  • Port
  • QueueManager
    • 消息队列的管理者
  • ConnectionNameList
    • 集群cluster,一个队列管理器属于多个集群
  • ClientReconnectOptions
  • CCSID
  • TransportType

API

依赖:
* mq-x
* connector-x
* jmqi-x
* commonservices-x
* headers-x
* mqjms-x

    public static void send(String qName, String msg) throws MQException, IOException {        Hashtable<String, Object> properties = new Hashtable<String, Object>();        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 进行管理 (最多无用连接、超时等等)。

spring-CachingConnectionFactory

依赖:
* 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> 

注意项

  1. Return code=2082 MQRC_UNKNOWN_ALIAS_BASE_Q opening a queue in the cluster.

    just leave the baseQueueManagerName blank
    reference

  2. 发送时,当有多个queue时,建议使用

    jmsTemplate.convertAndSend(QueueName, msg);

JNDI

配置

  • tomcat
<!-- Context.xml start --><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" /><!-- Context.xml end --><!-- spring cfg start --><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> <!-- spring cfg end -->

Java code

@AutoWiredJmsTemplate jmsTemplate;...jmsTemplate.convertAndSend(msg);jmsTemplate.convertAndSend(destinationName, msg);...

ps:省略了MQ Interface上Queue和其他的配置

原创粉丝点击