2017-04-03 1 views
1

우리는 JMS 메시지를 캡처하여 DB 테이블에 유지하기 위해 Spring 부트 및 JDBC를 사용하고 있습니다.Java - Oracle 테이블에 JMS 메시지 스트리밍

가능한 한 메모리 사용량을 줄이기 위해 이러한 메시지를 DB로 스트리밍하여 일괄 처리합니다.

이러한 메시지를 데이터베이스로 스트리밍 할 수 있습니까?

현재 JMS 대기열에서 여러 JMS 리스너가 사용됩니다. 이러한 리스너는 메시지를 쓰는 LinkedBlockingQueue (서비스에 의해 래핑 됨)를 공유합니다. 이 대기열은 List에 저장된 결과가 고갈 될 때까지 사용됩니다. 이 결과는 Spring의 JdbcTemplate을 사용하여 유지됩니다.

중간 저장 목록에 이러한 메시지가 저장되어 있기 때문에 메모리 사용 공간을 줄이려고합니다.

이 경우 따라야 할 조언이나 입증 된 패턴이 있습니까?

+1

? 메시지의 소비가 트랜잭션 인 경우 그 트랜잭션의 일부로 결과를 유지해야합니다. JVM, 네트워크 등이 다운되면 대기열에있는 결과가 어떻게 복구 될까요? –

+0

트랜잭션 경계와 관련된 좋은 점. 나는 한 번에 2000이라는 메시지 목록을 소비하고 멋진 배치 메커니즘을 추가하지 않고 메시지를 유지하는 것이 더 나은 옵션이라고 생각합니다. 트랜잭션 경계는 리스너 레벨에 있습니다. 이렇게하면 우리는 여전히 소비되었거나 소비되지 않은 것과 일관성을 유지할 수 있습니다. 대기열에 밀어 넣으면 트랜잭션 정보가 손실됩니다. –

답변

0

편리한 StreamEx 라이브러리를 사용하여 스트림을 청크 할 수있었습니다. 그러나 스트림 materialization시 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)); 
         } 
        }); 
     }