2016-07-25 110 views
0

我想從Java程序中將消息發送到Queue,我遇到了一個問題,它說它無法連接到主機&看起來它不是能夠閱讀頻道。從Java程序寫入消息到隊列時發生Websphere MQ問題

下面是從AMERR01.log誤差

----- amqccita.c : 4113 ------------------------------------------------------- 
07/25/2016 07:04:29 AM - Process(18280.26) User(mqm) Program(amqrmppa) 
        Host(ip-10-0-0-238) Installation(Installation1) 
        VRMF(8.0.0.4) QMgr(CSBTS.QUEUE.MANAGER) 

AMQ9209: Connection to host 'ip-10-0-0-238 (10.0.0.238)' for channel 'CHAN2' 
closed. 

EXPLANATION: 
An error occurred receiving data from 'ip-10-0-0-238 (10.0.0.238)' over TCP/IP. 
The connection to the remote host has unexpectedly terminated. 

The channel name is 'CHAN2'; in some cases it cannot be determined and so is 
shown as '????'. 
ACTION: 
Tell the systems administrator. 

這裏是Java代碼,

package com.sample.mq.client.ClientMQ; 

import java.io.IOException; 

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; 

/** 
* Java class to connect to MQ. Post and Retreive messages. 
* 
*/ 
public class MQClientTest { 

    String qMngrStr = "CSBTS.QUEUE.MANAGER"; 
    String user = "mqm"; 
    String password = "[email protected]"; 
    String queueName = "CSBTS.DEAL"; 
    String hostName = "10.0.0.238"; 
    int port = 1414; 
    String channel = "CHAN2"; 
    //message to put on MQ. 
    String msg = "Hello World, WelCome to MQ."; 
    //Create a default local queue. 
    MQQueue defaultLocalQueue; 
    MQQueueManager qManager; 

    /** 
    * Initialize the MQ 
    * 
    */ 
    public void init(){ 

     //Set MQ connection credentials to MQ Envorinment. 
     MQEnvironment.hostname = hostname; 
     MQEnvironment.channel = channel; 
     MQEnvironment.port = port; 
     MQEnvironment.userID = user; 
     MQEnvironment.password = password; 
     //set transport properties. 
     MQEnvironment.properties.put(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT); 

     try { 
      //initialize MQ manager. 
      qManager = new MQQueueManager(qMngrStr); 
     } catch (MQException e) { 
      e.printStackTrace(); 
     } 
    } 

    /** 
    * Method to put message to MQ. 
    * 
    */ 
    public void putAndGetMessage(){ 

     int openOptions = MQC.MQOO_INPUT_AS_Q_DEF | MQC.MQOO_OUTPUT; 
     try { 
      defaultLocalQueue = qManager.accessQueue(queueName, openOptions); 

      MQMessage putMessage = new MQMessage(); 
      putMessage.writeUTF(msg); 

      //specify the message options... 
      MQPutMessageOptions pmo = new MQPutMessageOptions(); 
      // accept 
      // put the message on the queue 
      defaultLocalQueue.put(putMessage, pmo); 

      System.out.println("Message is put on MQ."); 

      //get message from MQ. 
      MQMessage getMessages = new MQMessage(); 
      //assign message id to get message. 
      getMessages.messageId = putMessage.messageId; 

      //get message options. 
      MQGetMessageOptions gmo = new MQGetMessageOptions(); 
      defaultLocalQueue.get(getMessages, gmo); 

      String retreivedMsg = getMessages.readUTF(); 
      System.out.println("Message got from MQ: "+retreivedMsg); 

     } catch (MQException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 

    public static void main(String[] args) { 

     System.out.println("Processing Main..."); 

     MQClientTest clientTest = new MQClientTest(); 

     //initialize MQ. 
     clientTest.init(); 

     //put and retreive message from MQ. 
     clientTest.putAndGetMessage(); 

     System.out.println("Done!"); 
    } 

} 

我試圖讀取命令行隊列中的消息,

./amqsget CSBTS.DEAL CSBTS.QUEUE.MANAGER 

我無法弄清楚是什麼問題,它是與連接或通道。 P.S我的頻道身份驗證已禁用。

+0

什麼是你從Java命令得到的輸出?我假設這不是您發佈的第一組輸出結果? – ipsi

+1

1.請發佈運行程序時得到的異常堆棧跟蹤。我們需要知道MQ原因碼。 2.嘗試獲取您要連接的隊列管理器的AMQERR01.log,爲什麼連接終止的關鍵信息位可能在那裏。如果根本沒有關於連接的信息,那麼也許你使用的是錯誤的端口並且根本不連接到MQ。 3.嘗試使用MQ示例連接到隊列管理器,運行amqsput(samples/bin目錄中的一個),看看會發生什麼。 –

回答

0

Harsha,在代碼中MQ Connection沒有斷開連接。你能否檢查QueueManager上的MQ Disconnect是否有幫助? (https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.5.0/com.ibm.mq.javadoc.doc/WMQJavaClasses/com/ibm/mq/MQQueueManager.html

您可以獲得關於此MQSeries線程的進一步見解(http://www.mqseries.net/phpBB2/viewtopic.php?t=60349&sid=7370d64b1edf8d305e8e6e980ea423e0),您會發現該錯誤是因爲應用程序未正確從QM斷開連接。

2

Hummmm,從哪裏開始?

(1)這是一些不好的代碼。您的問題不是渠道或證書,而是您缺乏代碼。即使你沒有意識到這一點,你的代碼實際上是從隊列中放入並檢索一條消息。 MQ日誌中錯誤消息的原因是因爲隊列管理器對您的代碼表示了WTF。編程101,如果連接到它,然後斷開連接。如果你打開它,然後關閉它,當你完成。不要懶惰,並假設別的東西會清理垃圾。因此,日誌消息的原因是因爲您沒有關閉並從隊列管理器斷開連接,並且它表示WTF。 (2)不要使用MQEnvironment類,而應將連接信息放在Hashtable中並將其傳遞給MQQueueManager類。 MQEnvironment不是線程安全的。 (3)如果你想匹配MQGET上的MsgID和/或CorrelID,那麼你實際上必須告訴隊列管理器它(參見下面的'gmo.matchOptions')。 (4)將FAIL_IF_QUIESCING選項添加到所有MQ API調用 - 良好的編程習慣。

這裏是你的代碼更新,以便隊列管理器不說WTF:

import java.io.IOException; 
import java.util.Hashtable; 

import com.ibm.mq.*; 
import com.ibm.mq.constants.CMQC; 

/** 
* Java class to connect to MQ. Post and Retrieve messages. 
* 
* Sample Command Line Parameters 
* -h 127.0.0.1 -p 1414 -c TEST.CHL -m MQA1 -q TEST.Q1 -u userid -x password 
*/ 
public class MQClientTest 
{ 
    private Hashtable<String, String> params = null; 
    private Hashtable<String, Object> mqht = null; 
    private String qManager; 
    private String inputQName; 

    /** 
    * The constructor 
    */ 
    public MQClientTest() 
    { 
     super(); 
    } 

    /** 
    * Make sure the required parameters are present. 
    * 
    * @return true/false 
    */ 
    private boolean allParamsPresent() 
    { 
     boolean b = params.containsKey("-h") && params.containsKey("-p") && 
        params.containsKey("-c") && params.containsKey("-m") && 
        params.containsKey("-u") && params.containsKey("-x") && 
        params.containsKey("-q"); 
     if (b) 
     { 
     try 
     { 
      Integer.parseInt((String) params.get("-p")); 
     } 
     catch (NumberFormatException e) 
     { 
      b = false; 
     } 
     } 

     return b; 
    } 

    /** 
    * Extract the command-line parameters and initialize the MQ variables. 
    * 
    * @param args 
    * @throws IllegalArgumentException 
    */ 
    private void init(String[] args) throws IllegalArgumentException 
    { 
     params = new Hashtable<String, String>(); 
     if (args.length > 0 && (args.length % 2) == 0) 
     { 
     for (int i = 0; i < args.length; i += 2) 
     { 
      params.put(args[i], args[i + 1]); 
     } 
     } 
     else 
     { 
     throw new IllegalArgumentException(); 
     } 

     if (allParamsPresent()) 
     { 
     qManager = (String) params.get("-m"); 
     inputQName = (String) params.get("-q"); 

     mqht = new Hashtable<String, Object>(); 

     mqht.put(CMQC.CHANNEL_PROPERTY, params.get("-c")); 
     mqht.put(CMQC.HOST_NAME_PROPERTY, params.get("-h")); 

     try 
     { 
      mqht.put(CMQC.PORT_PROPERTY, new Integer(params.get("-p"))); 
     } 
     catch (NumberFormatException e) 
     { 
      mqht.put(CMQC.PORT_PROPERTY, new Integer(1414)); 
     } 

     mqht.put(CMQC.USER_ID_PROPERTY, params.get("-u")); 
     mqht.put(CMQC.PASSWORD_PROPERTY, params.get("-x")); 

     // I don't want to see MQ exceptions at the console. 
     MQException.log = null; 
     } 
     else 
     { 
     throw new IllegalArgumentException(); 
     } 
    } 

    /** 
    * Method to put then get a message to/from a queue. 
    */ 
    public void putAndGetMessage() 
    { 
     MQQueueManager qMgr = null; 
     MQQueue  queue = null; 
     MQMessage  putMessage = null; 
     MQMessage  getMessage = null; 

     int openOptions = CMQC.MQOO_INPUT_AS_Q_DEF | CMQC.MQOO_OUTPUT + CMQC.MQOO_FAIL_IF_QUIESCING; 

     MQGetMessageOptions gmo = new MQGetMessageOptions(); 
     gmo.options = CMQC.MQGMO_NO_WAIT + CMQC.MQGMO_FAIL_IF_QUIESCING; 

     MQPutMessageOptions pmo = new MQPutMessageOptions(); 
     pmo.options = CMQC.MQPMO_FAIL_IF_QUIESCING; 

     String msg = "Hello World, WelCome to MQ."; 

     try 
     { 
     qMgr = new MQQueueManager(qManager, mqht); 
     queue = qMgr.accessQueue(inputQName, openOptions); 

     putMessage = new MQMessage(); 
     putMessage.writeUTF(msg); 

     // put the message on the queue 
     queue.put(putMessage, pmo); 

     System.out.println("Message is put on MQ."); 

     // get message from MQ. 
     getMessage = new MQMessage(); 
     // assign message id to get message. 
     getMessage.messageId = putMessage.messageId; 

     /* 
      * Tell the queue manager that we want a message with a specific MsgID. 
      */ 
     gmo.matchOptions = CMQC.MQMO_MATCH_MSG_ID; 

     // get message options. 
     queue.get(getMessage, gmo); 

     String retreivedMsg = getMessage.readUTF(); 
     System.out.println("Message got from MQ: " + retreivedMsg); 
     } 
     catch (MQException e) 
     { 
     System.err.println("CC=" + e.completionCode + " : RC=" + e.reasonCode); 
     } 
     catch (IOException e) 
     { 
     e.printStackTrace(); 
     } 
     finally 
     { 
     try 
     { 
      if (queue != null) 
       queue.close(); 
     } 
     catch (MQException e) 
     { 
      System.err.println("MQCLOSE CC=" + e.completionCode + " : RC=" 
        + e.reasonCode); 
     } 

     try 
     { 
      if (qMgr != null) 
       qMgr.disconnect(); 
     } 
     catch (MQException e2) 
     { 
      System.err.println("MQDISC CC=" + e2.completionCode + " : RC=" 
        + e2.reasonCode); 
     } 
     } 
    } 

    public static void main(String[] args) 
    { 
     System.out.println("Processing Main..."); 
     MQClientTest clientTest = new MQClientTest(); 

     try 
     { 
     // initialize MQ. 
     clientTest.init(args); 
     // put and retrieve message from MQ. 
     clientTest.putAndGetMessage(); 
     } 
     catch (IllegalArgumentException e) 
     { 
     System.out.println("Usage: java MQClientTest -h host -p port -c channel -m QueueManagerName -q QueueName -u userid -x password"); 
     System.exit(1); 
     } 

     System.out.println("Done!"); 
    } 
} 
+0

謝謝@Roger的回答,這很有幫助。但我設法通過刪除get部分來實現我的代碼工作,我的實際需求只是將其放入隊列中。 – Harsha

+0

確保您更新您的代碼以匹配我所做的評論和我提供的代碼示例。 – Roger