307.6. 고급 사용 노트
307.6.1. 플러그형 연결 리소스 관리
SJMS는 기본 제공 연결
풀링을 통해 JMS 연결 리소스 관리를 제공합니다. 이렇게 하면 타사 API 풀링 논리에 의존할 필요가 없습니다. 그러나 J2EE 또는 OSGi 컨테이너에서 제공하는 외부 연결 리소스 관리자와 같은 외부 연결 리소스 관리자를 사용해야 하는 경우가 있을 수 있습니다. 이 SJMS에서는 내부 SJMS 연결 풀링 기능을 재정의하는 데 사용할 수 있는 인터페이스를 제공합니다. 이 작업은 ConnectionResource
인터페이스를 통해 수행됩니다.
Connection
Resource 는 필요에 따라 연결 풀을 SJMS 구성 요소에 제공하는 데 사용되는 계약입니다. 사용자는 SJMS를 외부 연결 풀링 관리자와 통합해야 하는 경우 를 사용해야 합니다.
표준 ConnectionFactory
공급자의 경우 이 구성 요소에 최적화된 SJMS와 함께 제공되거나 확장되는 ConnectionFactoryResource
구현을 사용하는 것이 좋습니다.
다음은 ActiveMQ PooledConnectionFactory
와 함께 plugable ConnectionResource를 사용하는 예입니다.
public class AMQConnectionResource implements ConnectionResource { private PooledConnectionFactory pcf; public AMQConnectionResource(String connectString, int maxConnections) { super(); pcf = new PooledConnectionFactory(connectString); pcf.setMaxConnections(maxConnections); pcf.start(); } public void stop() { pcf.stop(); } @Override public Connection borrowConnection() throws Exception { Connection answer = pcf.createConnection(); answer.start(); return answer; } @Override public Connection borrowConnection(long timeout) throws Exception { // SNIPPED... } @Override public void returnConnection(Connection connection) throws Exception { // Do nothing since there isn't a way to return a Connection // to the instance of PooledConnectionFactory log.info("Connection returned"); } }
그런 다음 ConnectionResource
를 SjmsComponent
:에 전달합니다.
CamelContext camelContext = new DefaultCamelContext(); AMQConnectionResource pool = new AMQConnectionResource("tcp://localhost:33333", 1); SjmsComponent component = new SjmsComponent(); component.setConnectionResource(pool); camelContext.addComponent("sjms", component);
사용의 전체 예를 보려면 ConnectionResourceIT
를 참조하십시오.
307.6.2. 일괄 메시지 지원
SjmsProducer은 목록을 캡슐화하는 교환을 생성하여 메시지 컬렉션을 게시할 수 있도록 지원합니다
. 그런 다음 이 SjmsProducer을 사용하여 목록 내용을 반복하고 각 메시지를 개별적으로 게시합니다.
일괄 메시지를 생성할 때 각 메시지에 고유한 헤더를 설정해야 하는 경우 SJMS BatchMessage
클래스를 사용할 수 있습니다. SjmsProducer에 BatchMessage
목록이 발생하면 각 BatchMessage
를 반복하고 포함된 페이로드 및 헤더를 게시합니다.
다음은 BatchMessage 클래스를 사용하는 예입니다. 먼저 BatchMessage
목록을 생성합니다.
List<BatchMessage<String>> messages = new ArrayList<BatchMessage<String>>(); for (int i = 1; i <= messageCount; i++) { String body = "Hello World " + i; BatchMessage<String> message = new BatchMessage<String>(body, null); messages.add(message); }
그런 다음 목록을 게시합니다.
template.sendBody("sjms:queue:batch.queue", messages);
307.6.3. 사용자 정의 가능한 트랜잭션 커밋 전략(로컬 JMS 트랜잭션만 해당)
SJMS는 개발자에게 TransactionCommitStrategy
인터페이스를 사용하여 사용자 정의 및 플러그형 트랜잭션 전략을 생성할 수 있는 수단을 제공합니다. 이를 통해 사용자는 SessionTransactionSynchronization
에서 세션 커밋 시기를 결정하는 데 사용할 고유한 환경 집합을 정의할 수 있습니다. 사용 예는 다음 섹션에서 자세히 설명하는 BatchTransactionCommitStrategy
입니다.
307.6.4. Batch Consumers & Producers
SJMS 구성 요소는 Producer 및 Consumer 엔드포인트에서 로컬 JMS 트랜잭션 배치를 지원하도록 설계되었습니다. 그러나 각각에 대해 어떻게 취급되는지는 매우 다릅니다.
SJMS 소비자 엔드포인트는 연결된 Session으로 커밋하기 전에 X 메시지를 처리하는 간단한 구현입니다. 소비자에서 일괄 처리 트랜잭션을 활성화하려면 트랜잭션 매개 변수를 true로 설정한 다음 transactionBatchCount
를 추가하고 0보다 큰 값으로 설정하여 트랜잭션을 활성화합니다. 예를 들어 다음 구성은 10개의 메시지마다 Session을 커밋합니다.
sjms:queue:transacted.batch.consumer?transacted=true&transactionBatchCount=10
소비자 엔드포인트에서 배치를 처리하는 동안 예외가 발생하면 세션 롤백이 호출되어 메시지가 다음 사용 가능한 사용자에게 다시 전달됩니다. 또한 연결된 Session에 대한 BatchTransactionCommitStrategy
의 경우 카운터가 0으로 재설정됩니다. JMSRedelivered 헤더가 true로 설정된 메시지를 감시하기 위해 배치 메시지의 프로세서에 후크를 배치해야 합니다. 이는 메시지가 어느 시점에서 롤백되었으며 성공적인 처리 확인이 수행되어야 함을 나타냅니다.
트랜잭션된 배치 소비자는 또한 세션에서 열려 있는 트랜잭션을 커밋하기 전에 메시지 간에 기본 시간(5000ms)을 기다리는 내부 타이머 인스턴스를 전달합니다. 기본 값 5000ms(최소 1000ms)는 대부분의 사용 사례에 적합해야 하지만 추가 튜닝이 필요한 경우 transactionBatchTimeout
매개변수를 설정합니다.
sjms:queue:transacted.batch.consumer?transacted=true&transactionBatchCount=10&transactionBatchTimeout=2000
컨텍스트 전환의 양이 이점을 얻지 않고 불필요한 성능에 영향을 미칠 수 있기 때문에 허용되는 최소 값은 1000ms입니다.
그러나 생산자 끝점은 훨씬 다르게 처리됩니다. 각 메시지가 대상에 전달된 후 생산자를 사용하면 교환이 종료되고 해당 메시지에 대한 참조가 더 이상 없습니다. Redelivery에 대한 모든 메시지를 사용할 수 있도록 하려면 BatchMessages를 게시하는 Producer Endpoint에서 트랜잭션을 간단히 활성화할 수 있습니다. 트랜잭션은 일괄 처리 목록의 모든 메시지를 포함하는 교환 결과에서 커밋됩니다. 추가로 구성할 필요가 없습니다. 예를 들면 다음과 같습니다.
List<BatchMessage<String>> messages = new ArrayList<BatchMessage<String>>(); for (int i = 1; i <= messageCount; i++) { String body = "Hello World " + i; BatchMessage<String> message = new BatchMessage<String>(body, null); messages.add(message); }
이제 트랜잭션이 활성화된 목록을 게시합니다.
template.sendBody("sjms:queue:batch.queue?transacted=true", messages);