소비자가 실패 할 때 JMS 메시지의 재전송을 보장해야하지만 여기에서 비슷한 질문에 허용되는 전략이 내 케이스에 적용되지 않을 수 있습니다.클라이언트가 충돌했을 때 JMS 메시지 재전송을 보장하는 방법
JMS 클라이언트 - 스프링 + activeMq - 손실되거나 복제 될 수없는 메시지를받는 경우를 고려하십시오. 메시지 처리에 비용이 많이 들기 때문에 클라이언트는이를 일괄 적으로 처리합니다. 이 시나리오는 다음과 같이한다 :
- T1이 - 클라이언트가받는 메시지 A, B, C 및 D
- T2 - 스레드는 클라이언트에서 깨어 메시지 A, B 및 C
- T3를 처리하기로 결정 - 클라이언트가 메시지 E 및 F를 수신합니다.
- T4 - 스레드가 A, B 및 C를 처리 한 상태로 반환됩니다. 그러면 다른 스레드가 아직 수행하지 않은 경우 다음 배치를 선택할 수 있습니다.
생산자 이제 설정 방법 - DefaultJmsListenerContainerFactory 및 Session.AUTO_ACKNOWLEDGE - 메시지가 그들이 스레드에 의해 선택되었는지의 여부, 즉시 전달 될 때 제거됩니다. 클라이언트가 T4 직전에 다운되면 메시지 A ~ F가 손실됩니다.
내가 T4 후)을 msg.acknowledge를 (호출하는 각 스레드를 생산자에 에게 Session.CLIENT_ACKNOWLEDGE를 사용을 계획했지만, documentation에 따라, 또한 어떤 될 것입니다, E와 F를 인정합니다 T4 이후에 클라이언트가 실패하면 손실됩니다.
트랜잭션 완료 세션이 처리 된 동안 만 메시지 A에서 F까지 처리하므로 트랜잭션 처리 세션이 도움이 될 것으로 확신하지는 않습니다.
내 목표는 고객의 실패의 경우에 대비하여 VM이 다운되면 스레드에 의해 성공적으로 처리되지 않은 모든 메시지가 주제/대기열에 남아 있습니다. 그런 다음 고객이 백업 할 때 픽업 할 수 있습니다.
어떻게하면이 아이디어를 얻을 수 있습니까?
S는
예, auto_ack은 onMessage()가 완료되면 수행됩니다. 현재이 메서드는 메시지를 컬렉션에 추가하기 만하면됩니다 (단순화하기 위해). 특정 조건이 충족되면 (시간, 콜렉션 크기 ...), 스레드는 콜렉션 내에서 메시지의 일부를 처리 할 시간이라고 결정합니다. 이것은 auto_ack에서 msg ack와 실제 처리 사이에 약간의 시간이있을 수 있음을 의미합니다. 어쩌면 제가 한 일은 실현 가능하지 않을 수도 있습니다. 그리고 여러분이 말했듯이, 최소한 잃을 여유가있는 msg의 최대 개수를 담을 수 있도록 컬렉션의 크기를 구성해야합니다. –
이 경우 실제로 mapdb 또는 smth와 같은 일부 영구 데이터 구조를 사용할 수 있습니다. 메시지가 일부 내부 채널로 전송 된 순간부터이 메시지가 더 이상 전송 된 후에는 사용자의 책임입니다. 브로커가이 작업을 수행하려고하면 복잡한 논리가 필요 없게됩니다. 하지만 나에게 있어서도 mapdb는 오버 헤드처럼 보일 뿐이며, 나는 당신의 경우에 훌륭한 아키텍처라고 의심한다. 저의 관점에서 볼 때 가장 좋은 옵션은 메시지의 일부 낮은 %를 잃거나 중복 될 수 있고 적절한 창 크기를 설정할 수 있다는 것입니다 –