2009-10-17 4 views
0

클라이언트에서 보낸 단일 JMS 메시지를 두 시스템에 정확하게 (정확히 한 번) 전달해야한다는 요구 사항이 있습니다. 이 두 시스템은 HA-사용할 수 없습니다, 그래서 생각 해낸 최고의 제안하는 것입니다 :JMS 메시지를 2 개의 대상으로 "복사"하는 방법은 무엇입니까?

  1. 에 대한 클라이언트의 게시물이 "중간"큐

  2. 을 설정 한 큐를 만들
  3. 은 사용자 정의 "DuplicatorMDB"를 사용하여 클라이언트 대기열에서 메시지를 읽고 같은 트랜잭션 내에서 두 개의 대기열에 게시합니다. 같은 기존의 기능

 
client->JMSDQ->DuplicatorMDB->Q1->MDB->System1 
          \->Q2->MDB->System2 

있습니까? 백엔드 시스템 중 하나 또는 둘 다 작동 중지 된 경우 시스템을 안정되게 유지하기 위해 시스템의 균형을 유지하는 적절한 방법은 무엇입니까?

응용 프로그램 서버는 웹 로직 (10)

내가 너무 많은 메시지 중복이 발생할 수 있기 때문에 클러스터 항목에 이것에 대한 주제를 사용할 수 있습니다. 우리는이 개 인스턴스가있는 경우, 다음 주제는 다음과 같이 갈 것이다 :

모든 메시지가 시스템 2에 두 번 시스템 1에 두 번 제공되며, 클러스터의 8 개 서버가있을 수 있습니다 경우에 따라서
 
client->Topic-->[email protected]>System1 
      | \->[email protected]>System2 
      \---->[email protected]>System1 
      \--->[email protected]>System2 

, 각 메시지를 8 번 배달됩니다. 이것은 내가 정말로 피하고 싶은 것입니다.

마침내 테스트 할 시간이있었습니다. 여기 내가 관찰 한 것이 있습니다 : 클러스터의 2 노드. 2 JMS 서버 : node1의 jms1, node2의 jms2. 분산 주제 dt. 영구 가입 및 jms-client-id = durableSubscriber가있는 MDB. 시스템을 시작했습니다 : 0 메시지, mdb @ node1이 가동되고 mdb @ node2가 주기적으로 연결을 시도하지만 "클라이언트 ID, durableSubscriber가 사용 중이므로"할 수 없습니다. 예상대로.

메시지 수 : jms1 @ dt messages 현재 = 0, 메시지 총계 = 100, 소비자 현재 = 1 node1이 100 개의 메시지를 처리 ​​한 것을 볼 수 있습니다.
jms2 @ dt messages current = 100, messages total = 100, consumers current = 1 즉 "duplicate"메시지가 주제에서 보류 중입니다.

다른 100 개의 메시지가 전송되면 노드 1에서 100 개가 처리되고 node2에서 보류중인 200 개가 처리됩니다.

노드 1을 재부트하면 mdb @ node2가 dt에 다시 연결되고 "보류 중"메시지 처리가 시작됩니다. 노드 2에서 200 개의 메시지가 처리되었습니다.

node1이 가동 된 후 mdb @ node1은 dt에 연결할 수없고 mdb @ node2는 연결됩니다. 0 = 현재 메시지 DT

jms1 @ 메시지 0 = 총 0 = 현재 메시지 DT 0
jms2 @ = 현재 소비자가, 메시지 1

100 이상의 메시지 보내기 = 소비자 전류 200 총 모든 100 개의 메시지가 node2에서 처리되고 node1에서 삭제 된 것을 볼 수 있습니다.

jms1 @ 0 = 현재 메시지 DT, 메시지 = 100 소비자 전류 = 0
jms2 @ 메시지 = 0, 메시지 = 300 총 전류 dt가 소비자 전류 = 이제 노드 2를 재부팅 1

, MDB 전체 @ node1은 dt에 다시 연결합니다. 재부팅 후 mdb @ node2가 dt에 다시 연결되고 mdb @ node1이 dt에서 연결 해제됩니다. 0 = 현재 메시지 DT

jms1 @ 메시지 = 100 총 0 = 현재 메시지 DT 1
jms2 @ = 현재 소비자 메시지 0 = 총 전류 소비자 = 1 I (100) 메시지를 보내

, 모두 노드 1 항목에서 노드 2에서 처리 및 저장된다 : 100 = 현재 메시지 dt를

jms1 @ 메시지 0 = 현재 메시지 dt가 = 200 소비자 전류 = 1
jms2 @ 전체 메시지는 = 0, 소비자 총 현재 = 1

그렇다면 de2와 mdb @ node1이 주제에 다시 연결된 후 node1에서 100 개의 "보류중인 메시지"가 처리되는 것을 봅니다.

그래서 결과는 다음과 같습니다. 400 개의 메시지를 보냈습니다. 700 개는 MDB에서 처리했으며 300 개는 중복되었습니다.

MDB 재 연결이 예상대로 잘 작동하는 것처럼 보이지만 "활성"MDB를 호스트하는 노드가 다운되면 메시지가 복제 될 수 있습니다.

이것은 weblogic JMS 구현의 버그 또는 기능 일 수 있습니다.

+1

나는 뭔가를 놓친가요? 주제를 사용하지 않는 이유는 무엇입니까? – SingleShot

+0

영구 가입에 대한 의견이 있으십니까? –

답변

1

저는 Weblogic을 사용하지 않았지만 대부분의 JMS 솔루션에는 대기열 및 주제 개념이 있습니다. JMS Topic이 필요하다. 구독자가 등록되고 항목을 통해 메시지가 각 구독자에게 한 번 전달됩니다.

Configuration details.

업데이트 : 클러스터 된 환경에서 문제가 발생하는 경우 모든 항목이 올바르게 구성되었는지 확인해야합니다 (여기서는 JMS Topic Clustering에 대한 안내입니다). 클러스터링 할 때 Weblogic이 너무 비참하게 실패한다는 것은 이상하게 들립니다. 그래도 작동하지 않으면 JMS를 지원하는 제 3 자 메시징 대기열 (예 : RabbitMQ)을 조사 할 수 있으며이 문제는 발생하지 않습니다.

+0

클러스터에 너무 많은 메시지 복사본을 생성하는 항목에 문제가 있습니다. 게시물에 대한 업데이트를 참조하십시오. –

0

이것은 ESB 구현이 적용해야하는 종류의 동작입니다. 프로세싱 오버 헤드의 관점에서 큰 차이는 없겠지만 "배관"과 어플리케이션 코드 사이의 관심사를 분리하는 것이 유용 할 수 있습니다.

WebSphere JMS 구현은 이러한 요구 사항을 처리하는 중개를 설치하도록 지원합니다. WebLogic과 비슷한 점이 있는지, 또는 관련 ESB 제품이 귀하를위한 옵션인지는 모르겠지만 이러한 기능을 조사하는 것이 좋습니다. 현재 간단한 요구 사항이 있으며 코드도 충분하지만 몇 가지 사소한 추가 요구 사항 (예 :이 필드를 달러에서 파운드로 변환하여 목적지로 전송하기 전에이 필드를 다음과 같이 보낼 수는 없는지 상상하기 쉽습니다. 그 목적지에이 내용 ...) 그리고 lo! 당신은 당신 자신의 ESB를 쓰는 것을 알게됩니다.

+0

ESB IMO가 필요하지 않습니다. 주제가 있습니다. –

+0

나는 질문자의 경우 주제를 만들 수 없다는 원래의 주장을 계속하고 있었다. 사실 주제를 사용할 수 있다고 말한 것 같아요. 그럴 경우 그게 바람직하다고 생각합니다. 다시 말하지만, 가능한 한 일반적인 배관을 함축하는 것을 피하십시오. – djna

0

[...] 따라서 모든 메시지는 System1에 두 번 전달되고 System2에 두 번 전달되며 클러스터에 8 개의 서버가있는 경우 각 메시지는 8 번 배달됩니다. 이것은 내가 정말로 피하고 싶은 것입니다 ...

내구성이있는 구독에는 적합하지만 영구적으로는 적합하지 않습니다. 내구성을 위해 모든 MDB는 동일한 연결 ID와 구독 ID (기본적으로 MDB 이름을 기반으로 함)를 공유하므로 한 번에 하나의 MDB 만 메시지를 첨부하고받을 수 있습니다. 시도 할 첫 번째 MDB는 연결에 성공하고 다른 사용자는 충돌을 감지하고 실패하지만 다시 시도합니다. 따라서 내구력있는 주제 구독을 사용하면 트릭을 수행해야합니다.

+0

내 생각 엔 당신이 주제가 아닌 수신기의 속성이기 때문에 영구 가입을 의미하는 것 같습니다. MDB에 영구 가입이 있고이를 위해 ClientID를 지정해야하는 경우 MDB는 클러스터의 한 노드에만 배포 할 수 있습니다. 이미 동일한 클라이언트 ID를 가진 클라이언트가 있기 때문에 두 번째 노드에 대한 WLS 배포가 실패합니다. –

+0

WLS10 docs에서 : "구독 ID는 해당 항목에서 고유해야하므로 영구 주제가 포함 된 MDB는 클러스터의 여러 서버 인스턴스에서 실행할 수 없습니다." http://download.oracle.com/docs/cd/E12839_01/web.1111/e13719/message_beans.htm#i1161176 –

+0

예, 이것이 제가 의미하는 바입니다. 충분히 명확하지 않았습니다. 문서화에 관해서, 나는 당신이 보여주고 싶은 것이 확실하지 않습니다. 왜 전체 단락을 붙여 넣지 않았습니까? "가입 ID는 해당 주제에서 고유해야하므로 클러스터의 여러 서버 인스턴스에서 영구 주제가 포함 된 MDB를 실행할 수 없습니다. 서버에서 MDB의 첫 번째 인스턴스가 시작된 후 인스턴스의 경우 EJB의 추가 인스턴스가 다른 클러스터 된 서버에 성공적으로 배포 할 수 있지만 MDB가 시작되면 충돌이 감지되고 MDB 인스턴스가 JMS에 완전히 연결되지 않습니다. " –

관련 문제