2012-08-24 95 views
3

我目前有兩個客戶端(生產者/消費者),我試圖通過JMS發送一個大文件。我成功生成並將文件發送到JMS服務器沒有任何問題。問題是,當我嘗試使用該消息,我也得到了以下異常:在WebLogic中配置JMS消息大小:weblogic.socket.MaxMessageSizeExceededException

Aug 24, 2012 11:25:37 AM client.Client$1 onException 
SEVERE: Connection to the Server has been lost, will retry in 30 seconds. weblogic.jms.common.LostServerException: java.lang.Exception: weblogic.rjvm.PeerGoneException: ; nested exception is: 
    weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '10000080' bytes exceeds the configured maximum of: '10000000' bytes for protocol: 't3' 
<Aug 24, 2012 11:25:37 AM CDT> <Error> <Socket> <BEA-000403> <IOException occurred on socket: Socket[addr=127.0.0.1/127.0.0.1,port=7001,localport=51764] 
weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '10000080' bytes exceeds the configured maximum of: '10000000' bytes for protocol: 't3'. 
weblogic.socket.MaxMessageSizeExceededException: Incoming message of size: '10000080' bytes exceeds the configured maximum of: '10000000' bytes for protocol: 't3' 
    at weblogic.socket.BaseAbstractMuxableSocket.incrementBufferOffset(BaseAbstractMuxableSocket.java:174) 
    at weblogic.rjvm.t3.MuxableSocketT3.incrementBufferOffset(MuxableSocketT3.java:351) 
    at weblogic.socket.SocketMuxer.readFromSocket(SocketMuxer.java:983) 
    at weblogic.socket.SocketMuxer.readReadySocketOnce(SocketMuxer.java:922) 

我相信這與在WebLogic中我MaxMessage大小設置,而不是一個代碼問題做(當然我可能是錯誤)。這裏是我的最大郵件大小 WebLogic settings

settigns我不知道爲什麼我收到這個異常,因爲這個協議的最大郵件大小比例外是聲稱...任何想法是什麼大?

我也嘗試添加服務器啓動參數-Dweblogic.MaxMessageSize = 200000000,但無濟於事。 enter image description here

這裏是我設置MessageListener和消息使用者本身的一些代碼。

public boolean setClient(MessageListener listener) { 

     try { 
      Properties parm = new Properties(); 
      parm.setProperty("java.naming.factory.initial", 
        "weblogic.jndi.WLInitialContextFactory"); 
      parm.setProperty("java.naming.provider.url", iProps.getURL()); 
      parm.setProperty("java.naming.security.principal", iProps.getUser()); 
      parm.setProperty("java.naming.security.credentials", 
        iProps.getPassword()); 
      ctx = new InitialContext(parm); 
      final QueueConnectionFactory connectionFactory = (QueueConnectionFactory) ctx 
        .lookup(iProps.getConFactory()); 
      connection = connectionFactory.createQueueConnection(); 
      ((WLConnection) connection) 
        .setReconnectPolicy(JMSConstants.RECONNECT_POLICY_ALL); 
      ((WLConnection) connection).setReconnectBlockingMillis(30000L); 
      ((WLConnection) connection).setTotalReconnectPeriodMillis(-1L); 
      session = connection.createQueueSession(false, 
        Session.AUTO_ACKNOWLEDGE); 
      queue = (Queue) ctx.lookup(iProps.getQueue()); 
      // The following code in the switch statement is the only code that 
      // differs for the producer and consumer. 
      switch (cType) 
       { 
       case PRODUCER: { 
        producer = (WLMessageProducer) session 
          .createProducer(queue); 
        // Setting to send large files is done in WebLogic 
        // Administration Console. 
        // Set 
        producer.setSendTimeout(60000L); 
        break; 
       } 
       case CONSUMER: { 
        consumer = session.createConsumer(queue); 
        if (listener != null) { 
         consumer.setMessageListener(listener); 
        }else{ 
         log.warning("A Message listener was not set for the consumer, messages will not be acknowledged!"); 
        } 
        break; 
       } 
       default: 
        log.info("The client type " + cType.toString() 
          + " is not currently supported!"); 
        return false; 
       } 

      connection.setExceptionListener(new ExceptionListener() { 
       @Override 
       public void onException(JMSException arg0) { 
        Logger log2 = new MyLogger().getLogger("BPEL Client"); 
        if (arg0 instanceof LostServerException) { 
         log2.severe("Connection to the Server has been lost, will retry in 30 seconds. " 
           + arg0.toString()); 
        } else { 
         log2.severe(arg0.toString()); 
        } 

       } 
      }); 
      shutdownListener = new ShutdownListener(connection, session, producer, consumer); 

      connection.start(); 
      log.info("Successfully connected to " + iProps.getURL()); 
      return true; 
     } catch (JMSException je) { 
      log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. " 
        + je.getMessage()); 
      try { 
       Thread.sleep(30000L); 
      } catch (InterruptedException e) { 
       log.warning(e.toString()); 
      } 
      return setClient(listener); 
     } catch (Exception e) { 
      log.severe("Could not connect to the WebLogic Server, will retry in 30 seconds. " 
        + e.toString()); 
      try { 
       Thread.sleep(30000L); 
      } catch (InterruptedException ie) { 
       log.warning(ie.toString()); 
      } 
      return setClient(listener); 

     } 
    } 

這裏的消息監聽:

public class ConsumerListener implements MessageListener { 
    private Logger log; 
    private File destination; 
    private Execute instructions; 

    public ConsumerListener(Execute instructions, File destination) { 
     this.instructions = instructions; 
     this.destination = destination; 
     log = new MyLogger().getLogger("BPEL Client"); 
    } 

    @Override 
    public void onMessage(Message arg0) { 

     try { 
      if (arg0.getJMSRedelivered()) { 
       log.severe("A re-delivered message has been received, and it has been ignored!" 
         + arg0.toString()); 
      } else { 
       try { 
        if (arg0 instanceof TextMessage) { 
         consumeMessage((TextMessage) arg0); 

        } else if (arg0 instanceof BytesMessage) { 
         consumeMessage((BytesMessage) arg0); 
        } else { 
         log.warning("Currently, only TextMessages and BytesMessages are supported!"); 
        } 
       } catch (JMSException e) { 
        log.severe(e.toString()); 
       } catch (IOException e) { 
        log.severe(e.toString()); 
       } catch (Throwable t) { 
        log.severe(t.toString()); 
       } 
      } 
     } catch (JMSException e) { 
      log.severe(e.toString()); 
     } 
    } 

    /** 
    * Unwraps the JMS message received and creates a file and a control file if 
    * there are instructions present. 
    * 
    * @param textMessage 
    *   JMS message received to be consumed. 
    * @throws JMSException 
    * @throws IOException 
    */ 
    protected void consumeMessage(TextMessage textMessage) throws JMSException, 
      IOException { 
     // ***All properties should be lowercase. for example fileName 
     // should be 
     // filename.*** 
     String fileName = textMessage.getStringProperty("filename"); 
     if (fileName == null || fileName.isEmpty()) { 
      fileName = textMessage.getStringProperty("fileName"); 
     } 
     if (fileName != null && !fileName.isEmpty()) { 
      // Check if the 
      // file name is equal to the shutdown file. If it 
      // is, shutdown the consumer. This is probably not a good way to 
      // do this, as the program can no longer be shutdown locally! 

      // We have a file in the queue, need to create the file. 
      createFile(destination.getAbsolutePath() + "\\" + fileName, 
        textMessage.getText()); 
      log.info("Done creating the file"); 
      String inst = textMessage.getStringProperty("instructions"); 
      // If there are instructions included, then create the 
      // instruction file, and route the message based on this file. 
      if (inst != null && !inst.isEmpty()) { 
       // We need to rout the file. 
       log.info("Instructions found, executing instructions"); 
       String[] tokens = fileName.split("\\."); 
       String instFileName = "default.ctl"; 
       if (tokens.length == 2) { 
        instFileName = tokens[0] + ".ctl"; 
       } 
       File controlFile = createFile(destination.getAbsolutePath() 
         + "\\" + instFileName, inst); 
       Control control = new Control(controlFile); 
       instructions.execute(control); 
       log.info("Done executing instructions"); 
      } else { 
       log.info("No instructions were found"); 
      } 
      log.info("Done consuming message: " + textMessage.getJMSMessageID()); 
     } 

    } 

    /** 
    * Unwraps the JMS message received and creates a file and a control file if 
    * there are instructions present. 
    * 
    * @param bytesMessage 
    *   The bytes payload of the message. 
    * @throws JMSException 
    * @throws IOException 
    */ 
    protected void consumeMessage(BytesMessage bytesMessage) 
      throws JMSException, IOException { 
     // ***All properties should be lowercase. for example fileName 
     // should be 
     // filename.*** 
     log.info("CONSUME - 1"); 
     String fileName = bytesMessage.getStringProperty("filename"); 
     if (fileName == null || fileName.isEmpty()) { 
      fileName = bytesMessage.getStringProperty("fileName"); 
     } 
     if (fileName != null && !fileName.isEmpty()) { 
      // Check if the 
      // file name is equal to the shutdown file. If it 
      // is, shutdown the consumer. This is probably not a good way to 
      // do this, as the program can no longer be shutdown locally! 

      // We have a file in the queue, need to create the file. 
      byte[] payload = new byte[(int) bytesMessage.getBodyLength()]; 
      bytesMessage.readBytes(payload); 
      createFile(destination.getAbsolutePath() + "\\" + fileName, payload); 
      log.info("Done creating the file"); 
      String inst = bytesMessage.getStringProperty("instructions"); 
      // If there are instructions included, then create the 
      // instruction file, and route the message based on this file. 
      if (inst != null && !inst.isEmpty()) { 
       // We need to rout the file. 
       log.info("Instructions found, executing instructions"); 
       String[] tokens = fileName.split("\\."); 
       String instFileName = "default.ctl"; 
       if (tokens.length == 2) { 
        instFileName = tokens[0] + ".ctl"; 
       } 
       File controlFile = createFile(destination.getAbsolutePath() 
         + "\\" + instFileName, inst); 
       Control control = new Control(controlFile); 
       instructions.execute(control); 
       log.info("Done executing instructions"); 
      } else { 
       log.info("No instructions were found"); 
      } 
      log.info("Done consuming message: " 
        + bytesMessage.getJMSMessageID()); 
     } 

    } 

    /** 
    * Creates a file with the given filename (this should be an absolute path), 
    * and the text that is to be contained within the file. 
    * 
    * @param fileName 
    *   The filename including the absolute path of the file. 
    * @param fileText 
    *   The text to be contained within the file. 
    * @return The newly created file. 
    * @throws IOException 
    */ 
    protected File createFile(String fileName, String fileText) 
      throws IOException { 
     File toCreate = new File(fileName); 
     FileUtils.writeStringToFile(toCreate, fileText); 
     return toCreate; 
    } 

    /** 
    * Creates a file with the given filename (this should be an absolute path), 
    * and the text that is to be contained within the file. 
    * 
    * @param fileName 
    *   The filename including the absolute path of the f ile. 
    * @param fileBytes 
    *   The bytes to be contained within the file. 
    * @return The newly created file. 
    * @throws IOException 
    */ 
    protected File createFile(String fileName, byte[] fileBytes) 
      throws IOException { 
     File toCreate = new File(fileName); 
     FileUtils.writeByteArrayToFile(toCreate, fileBytes); 
     return toCreate; 
    } 
} 
+0

您可以嘗試更改羣集中的廣播類型。如果它已設置爲UNICAST,請忽略此設置。 – kukku

+0

我已經找到了問題,我沒有在客戶端應用程序上設置-Dweblogic.MaxMessageSize,它現在可以正常工作。 –

回答

8

您還必須從WLS控制檯增加的最大郵件大小如截圖所示所有託管服務器

之後執行重新啓動並且問題將被解決。

此外還有第二種替代解決方案。根據Oracle Tuning WebLogic JMS Doc

調諧MessageMaximum限制

如果消息的聚集體尺寸推到消費者比當前協議的最大消息大小更大(默認大小爲10 MB,並且在配置每個WebLogic Server實例使用控制檯,並且基於每個客戶端使用Dweblogic.MaxMessageSize命令行屬性),則消息傳遞失敗。

上的客戶機

您可能需要配置除了WebLogic Server實例的WebLogic客戶端,發送和接收大消息時設置的最大郵件大小。要設置最大郵件大小的客戶端上,使用以下命令行屬性:

-Dweblogic.MaxMessageSize

注:此設置適用於交付給客戶,不只是所有WebLogic Server網絡數據包JMS相關數據包

編輯:

這個問題可以通過在按照以下動作中的一個或多個來解決。

  • 配置系統屬性-Dweblogic.MaxMessageSize
  • 使用WLS控制檯管理所有的託管服務器增加最大郵件大小。 WLS控制檯中的步驟如下:服務器/協議/常規
  • 從WLS控制檯增加最大消息大小。在WLS控制檯的步驟是:隊列/配置/ Threshholds和配額/最大消息大小

PROCEDURE用於施加weblogic.MaxMessageSize屬性

保持的備份setDomainEnv文件。停止所有的服務器。在每個setDomainEnv文件中添加-Dweblogic.MaxMessageSize = yourValue,更具體地在EXTRA_JAVA_PROPERTIES行中添加。之後首先啓動ADMIN,當ADMIN處於RUNNING狀態時,啓動MANAGED服務器。

我希望這會有所幫助。

+0

感謝您的迴應,儘管我已經嘗試了這兩種方法,問題仍然存在。我不明白的是爲什麼我可以生成一個大的JMS消息並將其放在隊列中,但是我不能使用完全相同的JMS消息? –

+0

我已更新該帖子。你有沒有嘗試過所有3種可用的解決方案,它們都不能解決你的問題?您是否已在管理服務器和所有託管服務器中的WLS控制檯上配置了最大消息大小?謝謝 –

+0

我已經嘗試了所有3個選項,唯一的選項我不確定我正在做的是系統屬性。我用我設置屬性的位置圖像編輯了我的問題。這是正確的地方嗎?我已嘗試進行更改後重新啓動服務器,但我仍然收到相同的錯誤。 –

0

在我的情況下,設置-Dweblogic.MaxMessageSize可以解決問題。我的問題是什麼應該是郵件大小的最大限制?我們無法繼續增加 消息大小來解決此問題。除了 以外,還有其他方法可以優化這個值嗎?

+0

這將是您必須通過查找您發送的最大消息來發現自己的事情。 –

+0

我如何找到最大的t3訊息?我沒有看到任何機制在weblogic中記錄t3消息。 – sujikin

+0

您可以使用管理控制檯監視隊列,也可以使用企業管理器進行更多圖形佈局,但EM主要用於流量的實時視圖。另一種選擇是將該值設置爲最大可能數(這可以在配置MaxMessageSize時使用管理控制檯找到)。如果您的最大消息超過這個大小,那麼weblogic將無法支持它。 –