2015-04-17 84 views
2

我是MQ programmimg的新手。根据我的要求,我试图将示例XML消息放入队列中,并期望从响应队列返回响应。 我可以看到关联的频道在短时间内打开,几秒钟后关闭。请在下面找到我用于将消息放入队列的代码。要求解决此问题的宝贵意见。通过java代码关闭MQ通道

错误:

Process(12908.13579) User(abc) Program(amqrmppa) 
        Host(hostname) 
AMQ9208: Error on receive from host 10 (10.0.0.1). 
EXPLANATION: 
An error occurred receiving data from 10 (10.0.0.1) over TCP/IP. This may 
be due to a communications failure. 

代码中使用:

package com.company.mq; 


import java.io.DataInputStream; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.net.URL; 

import com.ibm.mq.MQC; 
import com.ibm.mq.MQEnvironment; 
import com.ibm.mq.MQException; 
import com.ibm.mq.MQGetMessageOptions; 
import com.ibm.mq.MQMessage; 
import com.ibm.mq.MQPutMessageOptions; 
import com.ibm.mq.MQQueue; 
import com.ibm.mq.MQQueueManager; 

public class MQConnection { 

       private static final String CORR_ID = "CORRELID"; 
       String qMgrStr = ""; 
       String hostName = "hostname"; 
       String password ="xxxx"; 
       String userName ="username"; 
       String putqueueName = "putqueuename"; 
       String getqueuename = "getqueuename "; 
       String channel = "channel"; 
       String replyToQueue = "replyToQueue"; 
       String replyToQueueManager = ""; 

       static String content = ""; 


       int port =10000; 

       MQQueue readQueue = null; 
       MQQueue writeQueue = null; 
       MQQueueManager qManager; 


       @SuppressWarnings("unchecked") 
       public void init(){        
           MQEnvironment.hostname =hostName; 
           MQEnvironment.channel = channel; 
           MQEnvironment.port = port; 
           MQEnvironment.userID = userName; 
           MQEnvironment.password = password; 
           MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT); 

           try { 
               qManager = new MQQueueManager(""); 
               System.out.println("qManager====>"+qManager); 
           }catch(Exception e){ 
               e.printStackTrace(); 
           } 
           try { 
               System.out.println("qManager==> hhh"+qManager); 
           } catch (Exception e) { 
               // TODO Auto-generated catch block 
               e.printStackTrace(); 
           } 
       } 

       public String putAndGetMessage() throws InterruptedException, IOException{ 

           int openOptions = MQC.MQOO_OUTPUT | MQC.MQPMO_SET_ALL_CONTEXT | MQC.MQOO_FAIL_IF_QUIESCING; 
           String msgString = content.toString(); 
           System.out.println("msgString=="+msgString); 
           int expiryTime =60000; 
           MQMessage getmessage = null; 
           int waitInterval =4000; 
           try { 
               System.out.println("qManager Desc==>"+qManager.getDescription()); 
               writeQueue =openWriteQueue(qManager,putqueueName); 

               MQMessage message = myPut(writeQueue,msgString,expiryTime,getqueuename); 

//            qManager.accessQueue(putqueueName, openOptions,null,null,null); 

               readQueue =openReadQueue(qManager,getqueuename); 

               getmessage =mqGet(readQueue,waitInterval,message.messageId); 


               /*MQMessage msg = new MQMessage(); 
               msg.messageType = MQC.MQMT_REQUEST; 
               msg.format = "MQSTR"; 
               // msg.characterSet = 500; 
               msg.persistence = MQC.MQPER_NOT_PERSISTENT; 
               msg.correlationId = CORR_ID.getBytes(); 
               // msg.messageId = CORR_ID.getBytes(); 
               msg.expiry= 10000;*/ 

               /*System.out.println("before"); 
               Thread.sleep(10000); 
               System.out.println("after");*/ 

               /*MQGetMessageOptions gmo = new MQGetMessageOptions(); 
               int openOptions1 = MQC.MQGMO_WAIT| MQC.MQGMO_CONVERT| MQC.MQGMO_FAIL_IF_QUIESCING; 
               System.out.println("in getqManager==>"+qManager); 
               readQueue = qManager.accessQueue(getqueuename, openOptions1); 
               System.out.println("deafaultQueue======>"+readQueue); 
               readQueue.get(getmessage,gmo); 
               System.out.println(getmessage.readInt()); 

               String retriveMsg = getmessage.readUTF(); 
               System.out.println("read===>"+retriveMsg);*/ 

           } catch(MQException e){ 
               e.printStackTrace(); 
           } 
           return getmessage.readString(getmessage.getMessageLength()); 


       } 


       private MQMessage mqGet(MQQueue readQueue2, int waitInterval, 
               byte[] corrID) throws MQException { 
           MQMessage responseMessage = new MQMessage(); 
           responseMessage.correlationId =corrID; 

           MQGetMessageOptions gmo = new MQGetMessageOptions(); 
           gmo.options =MQC.MQGMO_WAIT| MQC.MQGMO_CONVERT| MQC.MQGMO_FAIL_IF_QUIESCING; 
           gmo.matchOptions = MQC.MQMO_MATCH_CORREL_ID; 
           gmo.waitInterval = waitInterval; 
           // TODO Auto-generated method stub 
           readQueue2.get(responseMessage,gmo); 
           return responseMessage; 
       } 

       private MQQueue openReadQueue(MQQueueManager manager, String getqueuename2) throws MQException { 
           // TODO Auto-generated method stub 
           return openQueue(manager,getqueuename2,MQC.MQOO_INPUT_SHARED | MQC.MQOO_INQUIRE |MQC.MQOO_FAIL_IF_QUIESCING); 
       } 

       private MQMessage myPut(MQQueue writeQueue2, String msgString, 
               int expiryTime, String getqueuename2) { 
           // TODO Auto-generated method stub 

           MQPutMessageOptions mpo =new MQPutMessageOptions(); 
           mpo.options = MQC.MQPMO_NEW_MSG_ID | MQC.MQMO_MATCH_CORREL_ID; 

           MQMessage putmessage = new MQMessage(); 
           putmessage.format = MQC.MQFMT_STRING; 
           putmessage.messageFlags = MQC.MQMT_REQUEST; 
           putmessage.replyToQueueName =replyToQueue; 
           putmessage.replyToQueueManagerName = qMgrStr; 
           putmessage.userId="userId"; 
           putmessage.expiry =expiryTime; 
           try { 
               putmessage.write(msgString.getBytes()); 
               try { 
                   writeQueue2.put(putmessage,mpo); 
               } catch (MQException e) { 
                   // TODO Auto-generated catch block 
                   e.printStackTrace(); 
               } 
           } catch (IOException e) { 
               // TODO Auto-generated catch block 
               e.printStackTrace(); 
           } 

           return putmessage; 
       } 

       private MQQueue openWriteQueue(MQQueueManager manager, String queueName) throws MQException{ 
           // TODO Auto-generated method stub 
           return openQueue(manager,queueName,MQC.MQOO_OUTPUT | MQC.MQPMO_SET_ALL_CONTEXT | MQC.MQOO_FAIL_IF_QUIESCING); 
       } 

       private MQQueue openQueue(MQQueueManager manager, String queueName, int options) throws MQException{ 
           // TODO Auto-generated method stub 
           return manager.accessQueue(queueName, options,null,null,null); 
       } 

       /** 
       * @param args 
       * @throws IOException 
       * @throws InterruptedException 
       */ 
       public static void main(String[] args) throws IOException, InterruptedException { 
           // TODO Auto-generated method stub 

           MQConnection conn = new MQConnection(); 

           DataInputStream dis = new DataInputStream (new FileInputStream ("c://request//Request.xml")); 

           byte[] datainBytes = new byte[dis.available()]; 
           dis.readFully(datainBytes); 
           dis.close(); 

           content = new String(datainBytes, 0, datainBytes.length); 
           //System.out.println("content===>"+content); 

           conn.init(); 
           System.out.println("connected"); 
           conn.putAndGetMessage(); 

       } 

} 
+0

您没有提及您使用的是哪个版本。你是否从应用程序中收到错误?我希望抛出某种异常...... –

+0

是否有指定为错误的一部分的MQ原因码?我猜你的问题中的错误消息来自队列管理器错误日志。如果是这样,这是完整的错误信息,因为它似乎比平常短很多? –

回答

1

应用似乎是它封装MQ I/O的类。在实例化时,init例程构造类并尝试连接到队列管理器。我能看到的代码存在一些问题。另外,我怀疑我知道代码失败的原因,但是问题中没有提供诊断信息,所以我只能猜测。我将首先描述问题,然后介绍我通常期望的诊断信息。

代码问题
该代码提供了用户标识和密码。除非这是一个v8.0客户端与v8.0队列管理器交谈,或者是一个使用出口通过TLS通道与MQ交谈的客户端,否则不会检查密码,也不需要密码。更糟糕的是,如果频道不是TLS并加密,则ID和密码将通过网络传输。取出密码。仅当应用程序提供的ID需要在连接请求中被覆盖时才使用该ID。

该代码不打印链接的异常。 JMS异常是一个多层次的数据结构,其中顶层是JMS理解它的异常,而较低层次的异常是运输提供者理解的异常。许多传输提供者,特别是纯Java编写的传输提供者,只使用数据结构的顶层,并且不提供链接的异常。但是,作为开发人员,您绝对不能认为这绝不会是这样。

JMS开发人员无法打印链接的异常没有任何正当理由。

当我在一家大型银行管理MQ管理团队,我的政策是,没事就去生产,如果不遵循下列规则:

  1. 当遇到一个JMS异常,代码打印链接的异常。
  2. 如果没有异常链接到JMS异常,则代码必须打印字符串“找不到链接的异常”,以便我们知道它至少查找了一个。

该代码将打开队列,并显示MQC.MQPMO_SET_ALL_CONTEXT选项。这种特权级别通常不授予非管理员用户。代码显式指定了一个ID,表明它没有以管理员权限运行。由于这些原因,我怀疑你得到了2035错误,当然你没有看到,因为代码无法打印链接的异常。

缺少诊断
MQ在版本和版本之间的行为不同。多年来,Java/JMS类已重新打包,重构并升级到JMS 1.1,然后升级到JMS 2.0。诊断问题,无论是发布在此处还是发送给MQ Admin tean进行生产中断,都应指出正在使用的MQ客户端和MQ服务器的版本。客户机节点和服务器节点上的dspmqver -a的输出总是有帮助的。

如前所述,链接的异常未被打印。没有它,堆栈跟踪可能是毫无价值的,所以一旦我不是失望没有提供堆栈跟踪。但是,更新代码以打印链接的异常并将来会包含堆栈跟踪。

客户端和服务器都产生错误日志。除了队列管理器的错误日志之外,服务器上还有全局错误日志,用于在队列管理器被识别之前发生的事情或者在全局MQ配置上运行的命令。在这种情况下,没有提供任何这些来源的错误日志信息。为什么不?

服务器还生成事件消息。这些通常由监视代理使用,但可以由管理员启用并进行审查以确定问题。在没有错误日志消息的情况下,事件消息可能非常有用。我不希望他们在这种情况下,但在这里提到它的完整性。

FDC文件由队列管理器生成并存储在与全局错误日志相同的目录中。这些提供比错误日志条目更详细的信息,但并不总是产生。通常,一个问题诊断请求会提到没有生成FDC文件,或者它们是,并提供它们的头部块。

资源
请参阅:

  • MQ Knowledge Center,如果你还没有找到它。
  • 特别是关于troubleshooting,
  • 的部分和关于linked exceptions的部分。 (虽然这些不是专门针对MQ,IBM至少已经提供了一些示例代码,您可以复制和粘贴。请务必粘贴为纯文本和纠正任何弯引号。)
  • MQ SupportPacs页,
  • ...尤其是MS0T是最新的MQ资源管理器(可与后台QMgrs一起使用),MS0P是一组插件,允许Explorer解析事件消息以及许多其他事情。
  • IBM的MQDev社区。虽然这对寻找文章和参考资料非常有用,但论坛却很平庸。
  • 对于一个社区,我更喜欢Vienna MQ list server或论坛MQSeries.net。两者都是开发人员,管理员和IBM人员的繁荣社区。
  • 当然,请继续在此处发帖标签。上述两个社区都没有为MQ开发完善的FAQ,并且Stack Overflow提供了该功能。有几位MQ老前辈和IBM人策划了Stack Overflow MQ标记。
  • 如果您可以管理资金和旅行,请参加MQ Tech Conference。IBM曾经举办过交易和消息传递会议,但将其与WebSphere的其余部分结合起来形成IMPACT。去年,它将包括IMPACT在内的多个会议组合到Interconnect中。 MQ技术大会全部都是MQ,而且价格非常便宜。由于IBM将MQ课程和培训外包,因此课堂培训是不太可行的选择,会议涵盖了课堂培训中未提供的材料。

坚持下去,祝你好运!

完全披露:我是创始人之一,我的MQ咨询公司是MQ技术大会的赞助商。然而,去年第一天它的MQ会话数量几乎与去年的第一天一样多,因为Interconnect整个星期都有,所以我在推荐它时没有看到利益冲突。