我是MQ programmimg的新手。根据我的要求,我试图将一个示例XML消息放入队列中,并期望从响应队列返回响应。 我可以看到相关频道短时间打开,持续几秒钟然后关闭。请在下面找到我用于将消息放入队列的代码。请求您解决此问题的宝贵意见。
错误:
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 :(得分:1)
应用程序似乎是一个封装MQ I / O的类。在实例化时,init
例程构造类并尝试连接到队列管理器。我可以看到代码存在一些问题。此外,我怀疑我知道为什么代码失败但问题中没有提供诊断信息所以我只能猜测。我首先描述问题,然后是我通常期望的诊断信息。
代码问题
该代码提供用户ID和密码。除非这是v8.0客户端与v8.0队列管理器或使用退出通过TLS通道与MQ通信的客户端进行通信,否则不会检查密码,也不需要密码。更糟糕的是,如果频道不是TLS并加密,则ID和密码将通过网络以明文形式传输。取出密码。仅当需要在连接请求中覆盖应用程序提供的ID时才使用ID。
代码未打印链接的异常。 JMS异常是一种多级数据结构,其中顶级是JMS理解它的异常,而较低级别的异常是传输提供者理解的异常。许多传输提供程序,尤其是那些使用纯Java编写的传输提供程序,只使用数据结构的顶层,并且不提供链接的异常。但是,作为开发人员,您不能认为这种情况永远不会发生。
没有正当理由让JMS开发人员无法打印链接的异常。
当我在一家大型银行管理MQ管理团队时,我的政策是,如果不遵守这些规则,则没有任何内容进入生产:
代码使用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咨询公司是MQ Tech会议的赞助商。然而,由于Interconnect已经整个星期,它在去年的第一天就有几乎一样多的MQ会话,所以我没有看到推荐它的利益冲突。