2014-01-10 5 views
0

시나리오 : JUST.CN이라는 대기열에 5 만 개의 메시지를 보냅니다. 그리고 하나의 메시지를 propertyString "myfilter = 'abc'를 1000 개의 메시지로 설정합니다. 이제는 동일한 셀렉터로 소비자를 생성하여 메시지를 소비합니다. 그러나 30000 개의 메시지 이후에 comsuming 속도가 매우 느립니다. activeMQ에서 기본 구성을 변경할 수 없습니다. 핵심 코드는 다음과 같습니다 :activeMQ의 소비자 선택기 문제

IDestination destination = SessionUtil.GetDestination(session, "JUST.CN"); 
        IMessageProducer producer = session.CreateProducer(destination); 
        string msg = "Hello hello hello world!~~testing~Hello hello hello world!~~testing~"; 

        for (int i = 0; i < 50000; i++) 
        { 
         ITextMessage message; 

         if (i % 1000 == 0) 
         { 
          message = session.CreateTextMessage(msg); 
          message.Properties.SetString("myfilter", "abc"); 
         } 
         else 
         { 
          message = session.CreateTextMessage(msg); 
         } 
         producer.Send(message, MsgDeliveryMode.Persistent, MsgPriority.Normal, TimeSpan.MinValue); 
        } 

소비자의 코드 :

IDestination destination = SessionUtil.GetDestination(session, "JUST.CN");    
IMessageConsumer consumer = session.CreateConsumer(destination, "myfilter='abc'", false); 

        int count = 0; 
        DateTime dtstart = DateTime.Now; 
       for (int i = 0; i < 50; i++) 
        { 
         IMessage iMsg = consumer.Receive(); 
         ITextMessage msg = (ITextMessage)iMsg; 
         Console.WriteLine(msg.Text); 
         count++; 

        } 
        DateTime dtend = DateTime.Now; 
        TimeSpan time = dtend - dtstart; 
        Console.WriteLine(time); 
        Console.WriteLine(count); 

내가 ActiveMQ를에 선택기 사용할 필요가 특별한 설정이 있습니까? 입력 사항을 미리 알려 주셔서 감사합니다.

답변

1

일반적으로 대기열에 메시지 선택기를 사용하는 것은 반대 패턴입니다. 블로그에 나온 이유에 대한 좋은 기사가 몇 년 전 Ade on Middleware에 있습니다.

대기열에서 메시지 선택기를 사용하려는 경우 일반적으로 특정 사용자는 일부 메시지에만 관심이 있습니다. 여기에 어떻게됩니까

<broker xmlns="http://activemq.apache.org/schema/core"> 
    <destinationInterceptors> 
    <virtualDestinationInterceptor> 
     <virtualDestinations> 
     <compositeQueue name="myapp.in" forwardOnly="true"> 
      <forwardTo> 
      <filteredDestination selector="myHeader > 5" queue="myapp.out.high"/> 
      <filteredDestination selector="myHeader <= 5" queue="myapp.out.low"/> 
      </forwardTo> 
     </compositeQueue> 
     </virtualDestinations> 
    </virtualDestinationInterceptor> 
    </destinationInterceptors> 
</broker> 

가 있다는 것입니다 : 당신은 선택 로직의 상당하다 (filteredDestination를 통해) 필터를 적용 브로커에 구성 composite destinations의 사용을 통해 훨씬 더 좋은 방법이 사용 사례를 해결할 수 메시지가 myapp.in 대기열에 도착하면 메시지에 대해 SQL92 필터가 실행되고 메시지는 적절히 정렬됩니다. 높은 메시지 만 사용하려는 구독자는 myapp.out.high에 가입합니다.

이렇게하면 효과적으로 문제를 뒤집어서 메시지를 소비 할 때 복잡한 처리가 필요하지 않게됩니다.

+0

제이크에게 감사드립니다. 답변이 많이 도움이됩니다. 가상 목적지를 만들고 메시지를 보내십시오. 대기열이 많아집니다. 단일 대기열을 사용하는 다른 방법이 있습니까? 특정 소비자에게 메시지를 보내면 모든 소비자에 대해 하나의 대기열을 만들 수있는 유일한 방법 일 것입니다.이 시스템에는 PTP에 대한 1000 명의 소비자가 있습니다. ActiveMQ Server에서 어떤 일이 벌어 질지 상상해보십시오. – Yolanda

+0

일반적으로 브로커에 많은 목적지가있는 것이 좋습니다. 비록 당신이 잘못된 기능을 사용하고있을지라도 (대기열이 당신의 특정 문제를 해결할 수있는 최선의 방법이 아닐 수도 있습니다) 소리가납니다. 당신이 달성하고자하는 것을 말할 수 있다면, 나는 올바른 방향으로 당신을 지적 할 수있을 것입니다. –

+0

우리 시스템에는 약 1000 명의 사용자가 있습니다. 서로간에 지점 간 통신을 실현하고 싶습니다. (아마도 동시에 300 명의 사용자가 온라인에있을 수 있습니다.) 그리고 메시지는 activemq에 영구 저장됩니다 예를 들어 userA는 userB에 하나의 메시지를 보냅니다. userB는 한 번 온라인으로 메시지를 수신합니다. 그리고 한 명의 사용자는 WebPage, Instant Communication Tool 및 Mobile의 클라이언트와 같이 3 가지 종류의 cliend-side를 갖습니다. 즉, 하나의 메시지가 useB의 모든 클라이언트 측으로 전송됩니다. 이것을 달성하는 좋은 방법이 있습니까? Jake에게 감사드립니다. – Yolanda