2011-02-16 2 views
3

메시지가 때때로 Q에서 두 번 이상 읽히는 경우가 있습니다. MQSeries 용 .NET 래퍼 (amqmdnet.dll)를 사용하고 Windows 서비스를 사용하여 메시지를 읽습니다.MQ 시리즈 메시지가 두 번 이상 읽음

Here's how I do it with VB.NET: 

'QManager 
Dim properties As Hashtable = New Hashtable(4) 

     properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_CLIENT) 
     properties.Add(MQC.CHANNEL_PROPERTY, channelName) 
     properties.Add(MQC.HOST_NAME_PROPERTY, iPAddress) 
     properties.Add(MQC.PORT_PROPERTY, port) 

     QManager = New MQQueueManager(queueManagerName, _ 
               properties) 


'Q itself 
getMessageOptions.Options = _ 
      MQC.MQGMO_FAIL_IF_QUIESCING Or _ 
      MQC.MQGMO_WAIT Or _ 
      MQC.MQGMO_SYNCPOINT 

getMessageOptions.WaitInterval = 1000 ' read from config 

Dim locker As New Object 

System.Threading.Monitor.Enter(locker) 

Q.Get(message, getMessageOptions) 

QManager.Commit() 

System.Threading.Monitor.Exit(locker) 

나는 Q.Get (메시지, getMessageOptions는) 다른 독자 사용할 수 없습니다 메시지가 차례로 QManager.Commit 그냥 .NET 픽 & 큐에서 유추에 의한 Q에서 메시지를 (제거하게 들었). 모니터 자체가 필요하지 않습니다.

내 Windows 서비스에서 여러 스레드가 Q를 읽었으며 낮은 폴링 간격 (100ms 이하)으로 인해 래퍼가 메시지의 '읽기'플래그를 업데이트 할 충분한 시간을 갖지 못해 의심 스럽습니다. 스레드를 겹쳐서 두 번 이상 올리십시오. 역사적으로 동일한 메시지는 최대 4 번 읽습니다.

폴링 간격을 늘리기 전에 올바른 일을하고 있는지 확인하고 싶었습니다. 누구든지 내 접근 방식으로 어떤 문제를 제안 할 수 있습니까?

감사합니다.

+0

많은 대기열 시스템은 "적어도 한 번", "한 번"또는 "한 번"과 같이 여러 가지 배달 보증을 지원합니다. MQ에 이러한 옵션이 있습니까? 그렇다면 어떤 옵션이 대기열에 선택되어 있습니까? –

+0

덕분에, Damien, 내가 아는 한 MQSeries는 '한 번만'배달 방법을 사용합니다. –

답변

5

하자의 주소 포스트와 이후의 설명에서 점의 수 :

  1. WMQ에서 GET을 수행 실제로 다른 독자들에게 메시지를 사용할 수 없도록 않습니다. syncpoint 외부의 GET은 메시지를 즉시 dequeue하는 반면, syncpoint 아래의 GET은 BACKOUT이 발생하지 않는 한 다른 독자가 메시지를 사용할 수 없게 만듭니다. 그러나 BROWSE 조작은 그러한 보호를 제공하지 않습니다.
  2. 큐 관리자는 메시지에 대한 액세스를 조정합니다. 큐 또는 메시지 내부의 MQ 응용 프로그램에 의한 직접 조작이 없으므로 .Net 래퍼가 "읽기 플래그"를 조작 할 수있는 기회가 없습니다.
  3. 대기 간격은 대기열에 사용 가능한 메시지가없고 해당 간격이 1 초인 값이 1000 인 경우 처리되지 않은 GET이 프로그램을 차단하는 기간입니다. 대기열에 많은 메시지가 있고 프로그램이 즉시 루프하면 유효 폴링 간격은 프로그램이 메시지를 처리하는 데 오래 걸립니다. 큐 관리자가 메시지 도착을 기다릴 필요가 없으므로 대기 간격은 깊은 큐에서 메시지를 큐 해제하는 처리량에 영향을 미치지 않습니다.
  4. WMQ는 다양한 수준의 안정성을 제공합니다. 이들은 메시지 지속성, 승인 모드 및 트랜잭션 성 등과 같은 요소에 의해 제어됩니다. 예를 들어, 작업 단위 (UOW) 외부에서 검색된 비 지속성 메시지는 한 번만 신뢰성을 제공합니다.
  5. 스레딩과 관련하여 동기화

는 WebSphere MQ : 닷넷 설명서 has this to say 사용 :

WebSphere®의 MQ .NET의 구현을 보장

해당 소정 접속 용 (MQQueueManager에 오브젝트 인스턴스), 목표에 대한 모든 액세스는 WebSphere MQ 큐 관리자는 입니다. 기본 동작은 에 대한 다른 모든 호출이 진행될 때까지 호출을 대기열 관리자에게 보내려는 스레드가 으로 차단된다는 의미입니다. 이 프로그램 내의 복수 스레드에서 동일한 큐 관리자 에 동시에 액세스해야하는 경우 동시 액세스가 필요한 각 스레드에 대해 새 MQQueueManager 오브젝트를 작성하십시오. (이 각 스레드에 대한 별도의 MQCONN 호출을 실행하는 것과하지 않습니다.)

기본 연결 옵션 MQC.MQCNO_HANDLE_SHARE_NONE 또는 MQC.MQCNO_SHARE_NO_BLOCK에 의해 오버라이드 (override) 을 경우 다음 큐 관리자가 동기화 가 더 이상이다.

그래서 동기화가 수행되지만 정확한 동작은 각 스레드가 자체 연결을 가지고 있는지 여부에 달려 있습니다. 이것은 트랜잭션이 연결 범위에 있기 때문입니다. 하나의 연결이 많은 스레드를 지원하고 스레드 중 하나가 COMMIT를 호출하면 해당 연결의 모든 스레드는 동일한 작업 단위 (UOW)에 있고 모두 COMMIT를 한 번에 호출합니다.

메시지를 탐색하는 것 외에 중복 메시지가 발생할 수있는 몇 가지 가능성이 있습니다. 이 모든 것은 백 아웃되는 메시지의 변형입니다. 백 아웃이 항상 프로그램 제어하에있는 것은 아닙니다. 많은 트랜잭션이 동기 점이 동시에 발생하면 MAXUMSGS, 로그 파일 1 차 및 2 차 익스텐트 및 여러 다른 튜닝 제한이 적용됩니다. 이 한도를 초과하는 경우, QMgr은 가장 오래된 작업 단위를 취소하여 다음 작업을위한 공간을 마련합니다. 백 아웃이 발생하는 또 다른 이유는 클라이언트 연결이 인터럽트 된 경우입니다. 이 경우 동기 점 아래에있는 GETS가 롤백되고 메시지를 다시 사용할 수있게됩니다.

이 문제가 발생하는지 확인하는 한 가지 방법은 메시지가 읽힐 때 백 아웃 카운트를 검사하는 것입니다. 강력한 메시징 응용 프로그램은 독점 메시지 처리의 일부로이 값을 정기적으로 검사하고 백 아웃 수가 임의의 임계 값을 초과하는 메시지를 다시 큐에 추가 (또는 삭제 및 로그)합니다. 이렇게하면 읽을 수없는 메시지가 스레드를 영구적으로 잠글 수 없습니다. 중복 메시지가 표시되면 임계 값을 초과하는 메시지를 단순히 다시 큐잉하는 것이 아니라 백 아웃 수가 0을 초과하는 모든 메시지를 로깅하는 것이 도움이 될 수 있습니다.

정확히 무슨 일이 일어나는지 보려면 tracing facilities of WMQ 또는 SupportPac MA0W을 사용하는 것이 좋습니다. 둘 중 하나는 수행되는 API 호출, 응용 프로그램 및 스레드, 그리고 어떤 옵션을 정확하게 표시합니다. 추적에서 중복 메시지가 BACKOUT이 발생하지 않고 탐색하지 않은 GET 호출로 전달되는 것으로 나타나면 수정 프로그램을 요청할 수있는 결함입니다.

구형 .Net 코드를 사용하면 문제가 해결되면서 약간의 문제가있을 수 있습니다. 나는 중복 된 메시지를 초래할 수정 목록에 어떤 결함도 보지 못했지만 .Net 클라이언트가 최근 v7에 없으면 곧 업그레이드 할 것을 고려해야합니다. v7 클래스는 훨씬 더 기능적이며 실제로 WMQ에 완전히 통합되어 지원됩니다. 2011 년 9 월 현재 WMQ v6의 지원 종료가 거의 없습니다. 최신 WMQ 클라이언트는 SupportPac MQC7에서 얻을 수 있습니다. v7 클라이언트를 이미 설치했고 v7.0.1.4로 업그레이드해야하는 경우 구형 v7 클라이언트를 통해 최신 클라이언트를 설치하거나 Recommended Fixes page에서 최신 수정 팩 (이 문서 작성 시점에서 FP 7.0.1.4)을 적용 할 수 있습니다. 수정 팩은 클라이언트 및 서버 설치를 업그레이드합니다.

+0

Starman! 이 문제에 대해 좀 더 자세히 설명해 드리며, 문제를 재현 할 수있는 방법이 있습니다.우리가 WinService를 멈출 때마다 (Q가 메시지를 계속 수신하는 동안) 5-10 분 후에 다시 시작하면 우리는 dup을 얻는다. 그것에 관한 어떤 생각? –

+1

이는 튜닝 문제로 인한 백 아웃을 제안합니다. 대기열이 충분히 깊어서 모든 스레드가 동시에 열린 작업 단위를 가질 수 있다는 조건이 있습니다. QMgr의 AMQERR01.LOG 파일은 트랜잭션을 취소하여 로그 공간 또는 UOW 핸들을 해제하는 경우 항목을 포함합니다. –

+1

고마워, T.Rob. 멀티 스레드 솔루션은 QManager 연결이 스레드 단위로 설정되어야한다고 말하고 있습니까? –