websphere mq问题

挖红薯 发布于 2016/02/16 16:18
阅读 693
收藏 1

最近的程序一直在和websphere mq打交道,但是遇到很多问题,网上查资料几乎查不到什么结果。。。主要有一下几个问题,求大神来解答

1、事务

我看有一些例子,比如《IBM WebSphere MQ基础教程》这本书中,无论是往mq放消息还是取消息都调用了qMgr.commit(),而网上一些例子都没有调用该方法。所以什么时候该用,什么时候不用?

2、多线程访问mq

未充分利用CPU提升效率,应用是多线程的。多个线程同时访问一个队列从里面取消息会有问题吗?还是IBM WebSphere MQ基础教程》这本书里有这么一段话:


但是,从网上某篇博客中又看到这么一句话:


我对访问mq的操作作了一个封装类MQGet,使用了单例。。。。应用是一个web应用,在servlet的init方法中先调用MQGet.getInstance().conn(),这样应用启动时就建立了连接;然后在开启的N多个线程中都调用MQGet.getInstance().getMsg()来取队列消息;在servlet的destroy方法中调用MQGet.getInstance().close()来关闭连接。

不知道这样做是否有问题,坐等大神指教。。

附MQGet类源码:

package com.tk.csc.service;

import org.apache.log4j.Logger;

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;

public class MQGet {
	private static final Logger logger = Logger.getLogger(MQGet.class);
	private static final String HOST = OverallProperties.getInstance().getPropertyStr("mqUrl");
	private static final int PORT = OverallProperties.getInstance().getPropertyInt("mqPort");
	private static final String CHANNEL = OverallProperties.getInstance().getPropertyStr("mqChannel");
	private static final String QMANAGER = OverallProperties.getInstance().getPropertyStr("mqManager");
	private static final String QNAME = OverallProperties.getInstance().getPropertyStr("mqName");
	private static final int CCSID = 1208;
	
	private static final MQGet m = new MQGet();
	
	private MQQueueManager qMgr;
	private MQQueue queue ;

	public static MQGet getInstance() {
		return m;
	}
	
	private MQGet() {}
	
	public boolean conn() {
		logger.info("trying to connect MQ:" + HOST+ ":" + PORT);
		MQEnvironment.hostname = HOST;
		MQEnvironment.channel = CHANNEL;
		MQEnvironment.CCSID = CCSID;
		MQEnvironment.port = PORT;
		MQEnvironment.properties.put("transport", "MQSeries");
		
		try {
			qMgr = new MQQueueManager(QMANAGER, 0);
		} catch (MQException e) {
			logger.info("create mqmanager fail!" + e.getMessage());
			return false;
		}
		
		try {
			queue = qMgr.accessQueue(QNAME, 8226, null, null, null);
		} catch (MQException e) {
			logger.info("accessQueue fail!" + e.getMessage());
			return false;
		}
		return true;
	}
	
	public String[]  getMsg() {
			
			int depth = 0;
			try {
				depth = queue.getCurrentDepth();
			} catch (MQException e1) {
				logger.info("get queue depth fail!" + e1.getMessage());
			}
			
			logger.info("当前队列深度==" + depth);
			
			if (depth <= 0) {
				return null;
			}
			
			MQGetMessageOptions gmo = new MQGetMessageOptions();
	        gmo.options = gmo.options + 2;
	        gmo.options = gmo.options + 8192;
	        
	        MQMessage rcvMsg = new MQMessage();
			try {
				queue.get(rcvMsg, gmo);
			} catch (MQException e) {
				logger.info("get msg from queue fail!" + e.getMessage());
			}
			String[] s = null;
			try {
				s = (String[]) rcvMsg.readObject();
			} catch (Exception e) {
				logger.info("execute readObject() fail!" + e.getMessage()); 
			}
			return s;
		
	}
	
	public void close() {
		if (queue != null) {
			try {
				queue.close();
				logger.info("close queue Success!");
			} catch (MQException e) {
				logger.info("colse queue fail!");
			}finally {
				if (qMgr != null) {
					try {
						qMgr.close();
						qMgr.disconnect();
						logger.info("close qMgr Success!");
					} catch (MQException e) {
						logger.info("close qMgr fail !");
					}
				}
			}
		}
	}

}



3、是否有可能有丢消息的情况?

在测试过程中偶尔出现队列深度queue.getCurrentDepth()一次减少2的情况,但是只有一个应用一个线程在取消息,每取走一条消息深度应该减1啊,,,

加载中
0
wangkang80
wangkang80
我所在的项目组经常跟IBM MQ打交道,但是从你问题描述上来看不清楚你到底是什么问题.
返回顶部
顶部