2010-07-27 3 views
1

내 프로그램이 .NET의 MessageQueue 클래스를 사용하여 MSMQ에서 성공적으로 읽을 수 있습니다. 대기열은 사용자가 구성 할 수 있으며 때로는 로컬 시스템에 있고, 때로는 원격 시스템에 있습니다. 사용자는 이름이나 IP 주소 및 대기열 이름 (그리고 "개인"대기열 만 사용)으로 원격 시스템을 지정할 수 있습니다.다른 컴퓨터의 MSMQ 수를 어떻게 읽을 수 있습니까?

대기열에 남아있는 메시지의 수를 사용자에게 표시하고 싶지만이를 수행 할 방법을 찾지 못했습니다. MessageQueue 클래스에는 Count (또는 이와 유사한) 속성이 없기 때문에 쉽게 알 수 있습니다.

PerformanceCounter 및 PerformanceCounterCategory 클래스를 사용하여 카운트를 얻을 수 있었지만 - 로컬 컴퓨터에서만이 기능이 제대로 작동하는 것 같습니다. (물론이 클래스를 올바르게 사용하고 있는지는 확실하지 않지만).

제 질문은 원격 컴퓨터의 MSMQ에서 Count (메시지 수)를 읽는 방법입니다.

답변

0

이것은 당신을위한 해결책이 될 수 있습니다 : http://jopinblog.wordpress.com/2008/03/12/counting-messages-in-an-msmq-messagequeue-from-c/

+0

보이는 것처럼 보입니다. 나는 그것을 시험해야 할 것이다. –

+0

이 페이지에서 몇 가지 메서드를 시도했지만 System.Messaging.MessageQueueException을 System.Messaging.MessageQueueErrorCode.RemoteMachineNotAvailable (소켓 개체가 실제로 개체를 읽을 수있는 것처럼 보였음)을 계속 가져 왔습니다. 해당 페이지의 메서드는 로컬 큐 (이미 작동하고있는)를 읽는 것으로 간주됩니다. 원격 큐의 수를 읽는 기술을 찾으려고합니다. –

+0

흠, 그게 너에게 잘 어울리지 않아서 미안해. 이 페이지에서 얻은 요점은이 방법이 모든 메시지를 들여다 보면서 커서를 사용하여 큐의 메시지를 계산한다는 것입니다. 그것은 많은 불필요한 독서를하고 있었기 때문에 이상적인 해결책처럼 보이지는 않았지만 잠재적 인 해결책처럼 보였습니다. 언급했듯이 대기열에서 읽는 방법은 원격으로 작동하지 않을 수도 있습니다. –

0

이 과잉 될 수도 있지만 당신은을 사용하여 수를 검색 할 수있을 거라고, 그래서 당신은 아마도 당신의 큐를 호스팅하는 동일한 컴퓨터에서 WCF 서비스를 넣을 수 있습니다 성능 카운터를 WCF 서비스에서 사용하고 해당 서비스의 메서드를 통해 해당 기능을 노출합니다.

0

여기 여러 가지를 말씀드립니다.

  • 내 자신의 답변을 받기 전에 John Opncar의 솔루션 (Dr. Wily 's Apprentice answer)에 대한 의견을 듣고 싶습니다. 그의 코드 을 원격 컴퓨터에서 작동시킵니다. 리모트 클러스터 서버의 대기열을보기 위해 그의 코드를 프로젝트에서 사용했으며, 은 매우 잘 작동합니다..

  • "RemoteMachineNotAvailable"오류가 발생하면 구성을 확인하십시오. 모든 컴퓨터가 같은 네트워크에 있거나 잊지 말아야합니까? 큐의 원격 컴퓨터의 보안 사용 권한이 다른 사용자가 읽을 수 있도록 설정되어 있습니까? 사용자/계정은 다른 시스템에서 읽을 수있는 충분한 권한이 있습니까?

예를 들어, 모든 사용자가 클러스터 된 대기열에 있어야합니다.

  • PerformanceCounters는 실제로 원격 컴퓨터의 메시지 속성을 읽는 데 문제가 있음을 알고 있습니다. Windows Server 클러스터 환경에서 대기열에 사용하려고 시도했지만 작동시키지 못했습니다. 그 당시 인터넷 조사를 한 적이 있었지만 보안상의 이유로 또는 단순히 버그 때문인지 불행히도 기억하지 못합니다. :-(

  • 이제 실제 대답

    .

    당신은 또한 MessageQueue.GetAllMessages() 또는 MessageQueue.GetMessageEnumerator 방법을 사용할 수 있습니다 존 Opincar에 의해 설명 된대로 커서-방법을 좋아하지 않는 경우에.

내가 GetMessageEnumerator을 해본 적이, 하지만 GetAllMessages()를 추천하지 않는다고 말할 수 있습니다.

수천 개의 메시지가 포함 된 여러 큐가있는 시스템에서 초마다을 사용하면 성능 문제가 발생합니다. 이 메서드는 대기열에있는 모든 메시지의 스냅 샷을 사용하므로 메모리와 네트워크에 과부하가 발생할 수 있습니다.

커서 방법은 다소 느립니다. 그러나 적어도 우리의 프로덕션 환경에서는 GetAllMessages() 솔루션을 사용했을 때보 다 훨씬 능숙합니다.

시나리오의 메시지 계산에 1 초가 필요하지 않으며 계산할 메시지가 적을 경우 GetAllMessages() 또는 GetMessageEnumerator()를 사용하면 해결할 수 있습니다.

마지막으로, 항상 개인적인 필요에 따라 달라집니다.

+0

추가 입력 해 주셔서 감사합니다.내 구현에 실수를했을 가능성이 있습니다. (코드를 VB로 변환해야만했습니다.) 하지만 다른 컴퓨터에서 읽을 수 있도록 대기열을 설정했음을 알고 있습니다. 사실, 원격 큐의 메시지를 성공적으로 읽는 동일한 개체에서 코드 계산 코드를 호출하고 있다고 생각했습니다. 다른 컴퓨터의 성능 모니터에서 원격 큐 크기를 표시 할 수 있습니다. –

+0

또한 대기열 크기는 종종 10,000 (가끔은 1,000,000 이상)이기 때문에 GetAllMessages가 나에게 도움이 될 것이라는 점 역시 매우 회의적입니다. 나는 다른 방법이 합리적인 시간 내에 작동한다는 것에 회의적이다 (예를 들어, 매 초마다 새로운 카운트를 표시 할 수있다). 난 정말 정말 열심히 놀랐어 - 특히 Perfmon 등, 그렇게 할 것 같다. NET을. 그냥 클래스에 Count 메서드를 추가 할 수 있습니다 ... –

+0

그동안 GetMessageEnumerator() 메서드를 사용해 보았습니다. . 처리 및 응답 시간은별로 변하지 않았습니다. 중요한 변경 사항은 하나뿐이었습니다. 오류 대기열에서 원래 대기열로 메시지를 이동할 때 훨씬 빠르게 작업 할 수 있습니다. 이 변경 작업을 시작하기 전에 몇 백 개의 메시지를 이동하는 데 몇 가지 조치가 필요할 수 있습니다. 이제 수천 개의 메시지까지 재 시도하는 데 단 몇 분만 걸립니다! –

3

로컬 큐에서 메시지 수를 가져 오는 가장 신뢰할 수있는 솔루션은 P/Invoke를 사용하여 MSMQ API를 사용하는 것입니다. 여기에 좋은 기사가 있습니다 : Counting the number of messages in a Message Queue in .NET.

원격 대기열에서 작동하는지는 잘 모르겠지만 사용하지 않을 것입니다. 일반적으로 원격 대기열을 사용하여 수행해야하는 유일한 작업은 메시지를 보내는 것입니다. 가능한 경우 원격 대기열에서 메시지 또는 등록 정보를 읽으려고하지 마십시오. "원격 및 로컬 읽기"는 항상 최상의 성능을 제공하며 모든 종류의 문제를 피할 수 있습니다 (예 : 원격 시스템을 사용할 수없는 경우).

+0

유망 해 보입니다. 기회가 생길 때마다 시도해 보겠습니다. 감사. –

+0

작업 링크 : http://blog.codebeside.org/blog/2008/08/27/counting-the-number-of-messages-in-a-message-queue-in/ – vossad01

4

다음과 같은 방법으로 메시지를 계산합니다.

 var machineName = "mymachine01"; 
     var formatName = "FormatName:DIRECT=OS:mymachine01\private$\ftpreceived": 
     try 
     { 
      var msmqManagement = new MSMQ.MSMQManagement(); 
      msmqManagement.Init(machineName, null, formatName); 
      return (uint)msmqManagement.MessageCount; 
     } 
     catch (COMException ex) 
     { 
      // If queue is not active or does not exist. 
      if (ex.ErrorCode == -1072824316) 
      { 
       return 0; 
      } 

      throw; 
     } 

주) 로컬 및 원격 큐 : 그것은 큐가 존재하지 또는 MSMQ Managment를 API는이 같은 오류하다고 판단 활성화되지 않는 경우 0을 반환합니다.

참고 : 컴퓨터 이름 값이 null이면 로컬 컴퓨터의 큐를 볼 수 있습니다.

주 : machinename 변수가 formatname의 machinename 부분과 다른 경우, machinename에 지정된 기계에서 주어진 형식 이름과 함께 "Outgoing"메시지 대기열에있는 메시지 수를 리턴합니다.

활성 상태는 메시지가 하나 이상 있거나 마지막 N 시간 내에 메시지가 있었음을 의미합니다. 대기 시간이 지나면 비활성 상태로 간주됩니다.

+3

이 작업을하려면 다음을 수행해야합니다. 여기에 표시된대로 MSMQ dll에 대한 참조를 추가하십시오. http://stackoverflow.com/questions/8234777/msmq-com-api-in-c-sharp/8258952#8258952 – Evan

1

이 정보를 얻기 위해 WMI를 사용하고 있습니다. 다음은이를 수행하기 위해 사용하고있는 코드 예제입니다.

  var query = String.Format("select MessagesinQueue from Win32_PerfRawdata_MSMQ_MSMQQueue where name ='{0}'", path.Replace("\\", "\\\\")); 
     var selectQuery = new SelectQuery(query); 
     using (var searcher = new ManagementObjectSearcher(selectQuery)) 
     using (var results = searcher.Get()) 
     { 
      foreach (var result in results) 
      { 
       var messages = result["MessagesinQueue"].ToString(); 
       return long.Parse(messages); 
      } 
     } 
관련 문제