乱了,乱了,分段消息不可以通过远程队列到集群的MQ队列中

 我在IBM MQ7和suse9的环境下做的开发。

 我在发送一个大文件消息时,使用分段的方式进行操作,处理完成后放到远程队列当中,到达下一个目的地。

 如果基于单独的mq的队列管理,如上的方法没有问题。但如果通过远程队列放到一个集群当中时,就会把一个完整的消息体四分五裂。在网上找N多资料,大都是要使用BIND_ON_OPEN做为打开的options。但每次都不管用。

 说下具体情况。

  QM_FIRST 表示要发送的队列管理器

  QM_PROXY 表示集群的代理服务器,也是一个队列管理器,属于集群ANT

       QM_EXE1 一个队列管理器,属于集群ANT,权重25%

       QM_EXE2 一个队列管理器,属于集群ANT,权重25%

       QM_EXE3 一个队列管理器,属于集群ANT,权重25%

       QM_EXE4 一个队列管理器,属于集群ANT,权重25%

 

      QM_FIRST通过对象UR_FIRST_TO_PROXY来完成于PROXY的发送。

 

  目前的效果。


 

  想要达到的效果。

 


 

      说明一下,远程队列的使用方式,远程队列通过一个别名队列QM_PROXY_ALIAS放在集群当中的本地队列当中。


 

  经过反复的论证和测试,发现这个问题的罪魁祸首就是这个远程队列,最后的解决方法是,弃用这个远程队列,直接连接到对方的集群当中的本地队列,也就是如上图的远程队列里。就可以了

  没有代码哟。大家可以自己直接写,比较简单,

 

  部分代码示例。
 private int SINGLE_MSG_MAX_LENGTH = 1048576; // 1M 默认是1M

/**
	 * 分段发送文件.
	 * 
	 * @param b
	 * @param queueName
	 * @throws QueueAccessException
	 */
	@SuppressWarnings("deprecation")
	public void putMessageMultiple(byte[] b, String queueName) throws QueueAccessException {

		MQQueue mqPut = null;
		try {
			mqPut = getPutQueue(queueName);

			int length, m, n;
			int packNum;

			length = b.length;

			m = length / SINGLE_MSG_MAX_LENGTH;
			n = length % SINGLE_MSG_MAX_LENGTH;

			if (n == 0) {
				packNum = m;
			} else {
				packNum = m + 1;
			}

			// second, put the msg to queue

			// 设置放消息时的参数
			for (int packCount = 1; packCount <= packNum; packCount++) {				
				MQMessage myMsg = new MQMessage();
				MQPutMessageOptions pmo = new MQPutMessageOptions();
				pmo.options = MQC.MQPMO_LOGICAL_ORDER + MQC.MQPMO_SYNCPOINT;
				if (packCount == packNum) {
					myMsg.messageFlags = MQC.MQMF_LAST_SEGMENT;
					if (n == 0) {						
						myMsg.write(b, (packCount - 1) * SINGLE_MSG_MAX_LENGTH, SINGLE_MSG_MAX_LENGTH);
					} else {						
						myMsg.write(b, (packCount - 1) * SINGLE_MSG_MAX_LENGTH, n);
					}
				} else {
					myMsg.messageFlags = MQC.MQMF_SEGMENT;
					
					myMsg.write(b, (packCount - 1) * SINGLE_MSG_MAX_LENGTH, SINGLE_MSG_MAX_LENGTH);
				}				
				mqPut.put(myMsg, pmo);
			}

		} catch (MQException e) {

			if (e.completionCode == MQException.MQCC_FAILED && e.reasonCode == MQException.MQRC_UNKNOWN_OBJECT_NAME) {
				throw new InvalidQueueException(queueName + " MQException occur  when getting the messsage.", e);
			} else {
				throw new QueueAccessException(queueName + " MQException occur  when sending  the messsage.", e);
			}

		} catch (IOException e) {

			throw new QueueAccessException(queueName + " IOException occur  when sending  the messsage.", e);
		}
	}

 

/**
	 * 得到发送消息队列的实例
	 */
	@SuppressWarnings("deprecation")
	private MQQueue getPutQueue(String queueName) throws MQException {
		MQQueue queue = null;
		queue = (MQQueue) putQueues.get(queueName);
		if (queue == null) {
			int openOptions = MQC.MQOO_OUTPUT | MQC.MQOO_FAIL_IF_QUIESCING;
			queue = qMgr.accessQueue(queueName, openOptions);
			putQueues.put(queueName, queue);
		}
		return queue;
	}

 

 

如上只是发送的代码。

 

 

如下是取出的代码。

 

 

/**
	 * 从队列中浏览分段消息
	 * 
	 * @param queueName
	 * @return byte[]
	 * @roseuid 447FA30301A0
	 */
	@SuppressWarnings("deprecation")
	public byte[] browseBigMessage(String queueName) throws QueueAccessException {

		byte[] b = null;
		byte[] retbb = null;

		ByteArrayOutputStream out = null;

		MQQueue browseQueue = null;
		try {
			browseQueue = getBrowseQueueBySeq(queueName);
			out = new ByteArrayOutputStream();
			MQMessage inMsg;

			// 设置取消息时的参数
			MQGetMessageOptions gmo = new MQGetMessageOptions();			
			
			gmo.options = MQC.MQGMO_LOGICAL_ORDER + MQC.MQGMO_SYNCPOINT + MQC.MQGMO_ALL_SEGMENTS_AVAILABLE;
			boolean isLastSegment = false;
			while (!isLastSegment) {
				inMsg = new MQMessage();
				browseQueue.get(inMsg, gmo);
				if (inMsg.messageFlags == MQC.MQMF_SEGMENT + MQC.MQMF_LAST_SEGMENT)
					isLastSegment = true;
				b = new byte[inMsg.getMessageLength()];
				inMsg.readFully(b);
				out.write(b);
				out.flush();
				b = null;
			}
			retbb = out.toByteArray();

		} catch (MQException e) {

			if (e.completionCode == MQException.MQCC_FAILED && e.reasonCode == MQException.MQRC_UNKNOWN_OBJECT_NAME) {
				throw new InvalidQueueException(queueName + " MQException occur  when browsing the messsage.", e);
			} else if (!(e.completionCode == 2 && e.reasonCode == 2033)) {
				throw new QueueAccessException(queueName + " MQException occur  when browsing the messsage.", e);
			}
		} catch (IOException e) {

			throw new QueueAccessException(queueName + " IOException occur  when browsing the messsage.", e);
		} catch (NumberFormatException e) {

			throw new QueueAccessException(queueName + " NumberFormatException occur  when browsing the messsage.", e);
		}
		return retbb;
	}


/**
	 * 得到浏览消息队列的实例,分段时实用
	 */
	@SuppressWarnings("deprecation")
	private MQQueue getBrowseQueueBySeq(String queueName) throws MQException {
		MQQueue queue = null;
		queue = (MQQueue) browseQueues.get(queueName);
		if (queue == null) {
			int openOptions = MQC.MQOO_INPUT_SHARED | MQC.MQOO_FAIL_IF_QUIESCING | MQC.MQOO_INQUIRE;// 本属性是browse and
			queue = qMgr.accessQueue(queueName, openOptions);
			browseQueues.put(queueName, queue);
		}
		return queue;
	}

 呵呵。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值