2011-11-27 4 views
4

JMS 공개 구독 모델을 사용하는 응용 프로그램을 작성하려고합니다. 그러나 나는 좌절감에 빠졌고, 게시자가 주제에서 메시지를 삭제할 수 있기를 원합니다. 유스 케이스는 내게 튼튼한 가입자가 있다는 것입니다. 활성화 된 사용자는 메시지를 받게 될 것입니다 (일시적이기 때문에). 비활성 상태이고 게시자가 메시지가 잘못되었다고 판단하면 메시지를 삭제할 수있게하려고합니다. 가입자가 활성화되면 가입자는 더 이상 수신하지 않습니다. 문제는, 어떻게 수행 할 수 있는지 모르겠습니다. 공급자에게 glassfish의 구현을 결정했지만 다른 대안이이 기능을 제공하면 전환 할 수 있습니다.주제에서 메시지를 제거하는 방법

감사합니다.

답변

6

JMS는 비동기 메시징 형식이므로 게시자와 구독자는 의도적으로 연결이 끊어집니다. 이것은 당신이 원하는 것을 할 수있는 메커니즘이 없다는 것을 의미합니다. 게시 시점에 활동중인 가입자의 경우, 제 시간에 삭제 메시지를 수신 할 기회없이 메시지를 사용합니다. 구독자가 오프라인이면 비동기 메시지는 원 자성을 갖습니다. 다른 응답자의 답을 디자인 할 때 (삭제 메시지를 작성하고 삭제 메시지를 찾기 위해 전체 대기열을 읽도록 다시 연결해야하는 경우) 구독자의 여부에 따라 시스템의 동작이 달라지는 상황이 발생하게됩니다 특정 메시지/삭제 조합이 게시 된 당시 온라인 상태인지 아닌지를 나타냅니다. 또한 게시자가 삭제 메시지를 전송하기 바로 전에 구독자가 보존 된 메시지를 읽는 경쟁 조건이 있습니다. 즉, 이러한 조건을 조정하고 경쟁 조건을 조정하기 위해 가입자에게 중요한 로직을 추가해야합니다.

이것을 수행하는 허용 된 방법은 "보상 거래"입니다. 생산자와 소비자가 하나의 작업 단위를 공유하지 않거나 공통 상태를 공유하지 않는 시스템 (예 : 동일한 DB를 사용하여 상태를 저장하는 시스템)에서 이전 트랜잭션을 취소하거나 수정하는 경우 첫 번째 트랜잭션을 반전하는 두 번째 트랜잭션이 필요합니다. 물론 소비자는 보상 거래를 올바르게 적용 할 수 있어야합니다. 이 패턴을 사용하면 소비자가 다시 시작된 후에 메시지가 실시간으로 또는 일괄 적으로 소비되는지 여부에 관계없이 모든 구독자가 동일한 동작을 보입니다.

보상 트랜잭션은 "메시지 삭제"와 다릅니다. 다른 응답자의 응답에서 제안 된 삭제 메시지는 메시지 스트림 자체에 영향을주는 명령 및 제어 형식입니다. 반면 보상 트랜잭션은 시스템 상태의 트랜잭션 업데이트를 통해 시스템 상태에 영향을줍니다.

일반적으로 은 명령 및 제어 기능으로 메시지 스트림을 조작하여 시스템 상태를 관리하려고합니다. 이것은 깨지기 쉽고 공격 받기 쉽고 감사 또는 디버그하기가 매우 어렵습니다. 대신 시스템이 모든 메시지를 서비스 제약 조건에 따라 전달하고 모든 메시지를 처리하도록 설계하십시오. 애플리케이션에서 상태 변경 (이전 동작 반전 포함)을 처리합니다.

예를 들어, 거래가 당좌 대월 수수료와 같은 2 차 효과를 유발하는 은행 업무에서 일반적인 절차는 당일 거래를 "메모 게시"한 다음 은행이 폐쇄 된 후에 일괄 적으로 정렬하고 적용하는 것입니다. 이를 통해 의 실수를 전에 조정할 수 있으므로 당좌 대월 수수료가 발생합니다. 최근에는 트랜잭션이 실시간으로 적용되지만 트리거는 하루의 책이 마감 될 때까지 보류되며 이는 동일한 결과를 얻습니다.

+0

+1, 귀하의 답변을 읽는 것이 항상 즐겁습니다. – MaDa

+0

고마워, 친절한 단어들! –

-1

생산자가 delete 메시지를 보내고 소비자가 처리를 시작하기 전에 모든 메시지를 읽어야합니다.

+0

고마워,이 부분의 전체 구현을 처리해야한다는 것을 의미하지만 가입자가 삭제 된 메시지를 볼 수는 있지만 기본적으로 무시한다는 것을 의미합니다. 실제로 메시지가 도달하지 못하도록하는 방법이 있습니까? – LuBa

+0

메시지는 만료 될 수 있습니다. –

1

JMS API는 대상 (대기열 또는 주제)에서 메시지를 제거하는 것을 허용하지 않습니다. 특정 JMX 제공 업체가 JMX를 사용하여 상태를 관리 할 수있는 고유 도구를 제공한다고 생각합니다. JMS 공급자를 확인해보십시오. 그러나 솔루션을 찾더라도 다른 JMS 공급자간에 이식 할 수는 없습니다.

메시지를 "제거"하는 하나의 합법적 인 방법은 유효 기간 : publish(Topic topic, Message message, int deliveryMode, int priority, long timeToLive)입니다. 아마도 그것은 당신에게 충분할 것입니다.

응용 프로그램에 해당되지 않는 경우 응용 프로그램 수준에서 문제를 해결하십시오. 예를 들어 각 메시지에 고유 ID를 첨부하고 동일한 ID로 "실제"메시지를 삭제하는 명령의 일종이 될 높은 우선 순위의 특수 "삭제"메시지를 게시하십시오.

관련 문제