2017-05-10 13 views
0

Javaで大きなMQメッセージを読み込み、MQメッセージの内容を処理してファイルに書き込む作業をしています。Javaで大きなMQオブジェクトを扱う

私が書いているコードはマルチスレッドであり、複数のメッセージを並行して処理することができます。

書き込みアプリケーションは、セグメンテーション+グループ化を使用して大きなMQメッセージをキューに書き込みます(PUT)。

今、以下の手順を読んでいます。

  1. MQGetMessageOptionsに適切な値を設定します。

    MQGetMessageOptions getGroupMsgOptions = new MQGetMessageOptions(); 
    getGroupMsgOptions.options = MQC.MQGMO_LOGICAL_ORDER | MQC.MQGMO_SYNCPOINT 
    | MQC.MQGMO_ALL_MSGS_AVAILABLE | MQC.MQGMO_COMPLETE_MSG; 
    
  2. 初期化MQQueue - serverFileQueueとMQMessage - reqMessage。

  3. reqMessageとgetGroupMsgOptionsを渡してMQQueueのgetメソッドを呼び出す。

    serverFileQueue.get(reqMessage, getGroupMsgOptions); 
    
  4. whileループのMQメッセージフラグをチェックして、グループ内の最後のメッセージの最後のセグメントを識別します。

  5. BufferedOutputStreamを使用してメッセージの内容をファイルに書き込みます。

MQメッセージが大きすぎると私の質問は、コードがjava.lang.OutOfMemoryErrorをを取得する必要がありますか?

ステップ3 serverFileQueue.get(...)がMQメッセージ全体をメモリにロードするかどうかを理解しようとしていますか?

セグメントのみがロードされるため、心配する必要はありませんjava.lang.OutOfMemoryError

答えて

2

メッセージはセグメント単位で取得されるため、OutofMemoryエラーについては心配する必要はありません。各セグメントは別個のMQGET呼び出しでなければならず、MQGMOのGroupStatusプロパティとSegmentStatusプロパティを使用して、メッセージ。

1

まず、MQはjava.lang.OutOfMemoryErrorをスローしません。 'subbaraoc'によると、コードは各メッセージセグメントに対してMQGETを実行し、すべてを再アセンブルするのはあなたのコードに任されています。

第2に、75 '100MB'セグメントがある場合、JVMは実行中の処理に十分なメモリがないため、java.lang.OutOfMemoryErrorをスローする可能性があります。

第3に、なぜホイールを再発明していますか?これは、あなたがやっていることを正確に行う、Javaで書かれた無料のオープンソースプロジェクトです。それはUniversal File Moverと呼ばれます。ソースコードをダウンロードして、コードがメッセージセグメンテーションをどのように扱うかを確認することができます。

1

オプションMQGMO_COMPLETE_MSGを含めると、QMはアプリケーションの論理メッセージをアセンブルします。したがって、getはメッセージ全体を返します。

前述のとおり、セグメントメッセージを取得してアプリケーションで論理メッセージをアセンブルすることは可能ですが、そのコードを変更する必要があります。いくつかのより詳細な説明:

https://www.ibm.com/support/knowledgecenter/SSFKSJ_8.0.0/com.ibm.mq.dev.doc/q026390_.htm

、道のグループ化によるセグメンテーションは、2つの非常に異なるものです。グルーピングは、別々の論理メッセージの順序を指定するために使用されますが、セグメント化では、1つの大きな論理メッセージを複数の小さなセグメントメッセージとして転送できます。セグメンテーションはグループ化を必要とせず、グループ化することを意味しません。 私は、あなたのケースでは、MQGMO_ALL_MSGS_AVAILABLEオプションはあまり意味がないので、代わりにMQGMO_ALL_SEGMENTS_AVAILABLEを使うべきだと思います。