2017-04-03 11 views
1

JMSメッセージをキャプチャしてDBテーブルに保持するために、SpringブートとJDBCを使用しています。Java - OracleテーブルへのJMSメッセージのストリーミング

できるだけメモリフットプリントを小さくするために、これらのメッセージをDBにストリームしてバッチコミットしたいと思います。

これらのメッセージをデータベースにストリーミングできますか?

現在、JMSキューから複数のJMSリスナーを使用しています。これらのリスナーは、メッセージを書き込むLinkedBlockingQueue(サービスでラップされています)を共有します。このキューは、結果がListに格納されるまで消費されます。これらの結果は、SpringのJdbcTemplateを使用して永続化されます。

これらのメッセージが中間リストに保存されるのは、一括保存を許可するためだけです。

この場合、アドバイスや実証済みのパターンはありますか?

+1

トランザクション境界と考えられていますか?メッセージの消費量がトランザクションの場合、結果はそのトランザクションの一部として永続化されるはずです。 JVM、ネットワークなどがダウンした場合、キュー内の結果はどのように回復しますか? –

+0

トランザクション境界に関する良い点。私はより良い選択肢は、一度に2000のようなメッセージのリストを消費し、単純なバッチ処理メカニズムを追加することなくそれらを永続させることだと考えています。トランザクションの境界はリスナーレベルにあります。このようにして、消費されていないものとの一貫性を維持します。キューにそれらをプッシュするだけで、トランザクション情報が失われることがわかります。 –

答えて

0

便利なStreamExライブラリを使用してストリームをチャンクすることができました。 しかし、ストリームのマテリアライゼーション時にはまだJVMメモリの問題が発生しています。さらなるパフォーマンスとガベージコレクションテストを実行する必要があります。次のように

ストリームするコードは次のとおりです。

try (StreamEx<MyEntity> stream = StreamEx.of(myEntities)) { 
      stream.groupRuns((prev, next) -> recordCounter.incrementAndGet() % myApplicationProperties.getBatchSize() != 0) 
        .forEach((chunk) -> { 
         if (chunk.size() != 1) { 
          jmsTemplate.convertAndSend(chunk); 
         } else { 
          jmsTemplate.convertAndSend(chunk.get(0)); 
         } 
        }); 
     } 
関連する問題