4

現在、2つのクライアント(プロデューサー/コンシューマー)があり、JMSを介して大きなファイルを送信しようとしています。ファイルを正常に作成し、JMSサーバーに問題なく送信しています。問題は、メッセージを消費しようとすると、次の例外が発生することです。

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設定

このプロトコルの最大メッセージサイズが例外が主張しているものよりも大きいため、なぜこの例外が発生するのかわかりません...何か考えはありますか?

サーバー開始引数-Dweblogic.MaxMessageSize=200000000も追加しようとしましたが、役に立ちませんでした。 ここに画像の説明を入力してください

これは、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);

        }
    }

これがMessageListenerです:

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;
    }
}
4

2 に答える 2

8

また、すべての管理対象サーバーのスクリーンショットに示すように、WLSコンソールから最大メッセージサイズを増やす必要があります。

その後、再起動を実行すると、問題が解決されます。

さらに、2番目の代替ソリューションがあります。Oracle Tuning WebLogic JMSドキュメントによると:

メッセージの調整最大制限

コンシューマにプッシュされるメッセージの集約サイズが現在のプロトコルの最大メッセージサイズよりも大きい場合(デフォルトサイズは10 MBで、コンソールを使用してWebLogic Serverインスタンスごとに、Dweblogic.MaxMessageSizeを使用してクライアントごとに構成されます)コマンドラインプロパティ)、メッセージ配信は失敗します。

クライアントでの最大メッセージサイズの設定

大きなメッセージを送受信する場合は、WebLogicServerインスタンスに加えてWebLogicクライアントを設定する必要がある場合があります。クライアントで最大メッセージサイズを設定するには、次のコマンドラインプロパティを使用します。

-Dweblogic.MaxMessageSize

注:この設定は、JMS関連のパケットだけでなく、クライアントに配信されるすべてのWebLogicServerネットワークパケットに適用されます

編集済み:

この問題は、以下の1つ以上のアクションに従うことで解決できます。

  • システムプロパティ-Dweblogic.MaxMessageSizeを構成します
  • 管理者およびすべての管理対象サーバーのWLSコンソールを使用して、最大メッセージサイズを増やします。WLSコンソールの手順は次のとおりです。サーバー/プロトコル/一般
  • WLSコンソールからの最大メッセージサイズを増やします。WLSコンソールの手順は次のとおりです。キュー/設定/しきい値とクォータ/最大メッセージサイズ

weblogic.MaxMessageSizeプロパティを適用するための手順

setDomainEnvファイルのバックアップを保持します。すべてのサーバーを停止します。各setDomainEnvファイル、より具体的にはEXTRA_JAVA_PROPERTIES行に-Dweblogic.MaxMessageSize=yourValueを追加します。その後、最初にADMINを起動し、ADMINのステータスがRUNNINGになったら、MANAGEDサーバーを起動します。

これがお役に立てば幸いです。

于 2012-08-25T06:12:34.470 に答える
0

私の場合、-Dweblogic.MaxMessageSizeを設定すると問題が解決しました。私の質問は、メッセージサイズの上限は何ですか?この問題を解決するためにメッセージサイズを増やし続けることはできません。他の特定の値に加えて、この値を最適化する方法はありますか?

于 2013-07-11T08:08:15.633 に答える