2013-10-28 2 views
1

대기열에서 항목을 처리하는 작업자 역할이 있습니다. 기본적으로 큐의 항목을 비우고 비동기 적으로 처리하는 무한 루프입니다.작업자 역할 프로세스 - 구성 값 폴링

작업자 역할을 변경할 때 다시 시작해야하는 두 가지 구성 설정 (PollingIntervalMessageGetLimit)이 있으므로 다시 시작하지 않아도됩니다.

private TimeSpan PollingInterval 
{ 
    get 
    { 
     return TimeSpan.FromSeconds(Convert.ToInt32(RoleEnvironment.GetConfigurationSettingValue("PollingIntervalSeconds"))); 
    } 
} 

private int MessageGetLimit 
{ 
    get 
    { 
     return Convert.ToInt32(RoleEnvironment.GetConfigurationSettingValue("MessageGetLimit")); 
    } 
} 

public override void Run() 
{ 
    while (true) 
    { 
     var messages = queue.GetMessages(MessageGetLimit); 

     if (messages.Count() > 0) 
     { 
      ProcessQueueMessages(messages); 
     } 
     else 
     { 
      Task.Delay(PollingInterval); 
     } 
    } 
} 

는 문제 : 피크 시간 동안

는, while 루프는 초당 몇 번을 실행 할 수있다. 즉, 하루에 최대 100,000 번까지 구성 항목을 쿼리하게됩니다.

이것은 해롭거나 비효율적입니까?

답변

2

Upfront disclaimer, 저는 RoleEnvironments를 사용하지 않았습니다.

GetConfigurationSettingValue에 대한 MDSN 설명서는 구성을 디스크에서 읽음을 나타냅니다. http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.serviceruntime.roleenvironment.getconfigurationsettingvalue.aspx. 따라서 자주 전화를 걸면 느려지 게됩니다.

또한 MSDN 설명서는 설정이 변경되면 이벤트가 발생 함을 보여줍니다. http://msdn.microsoft.com/en-us/library/microsoft.windowsazure.serviceruntime.roleenvironment.changed.aspx. 이 이벤트를 사용하여 실제로 변경된 설정 만 다시로드 할 수 있습니다.

여기에는 하나 (테스트되지 않은 컴파일되지 않은) 방법이 있습니다.

private TimeSpan mPollingInterval; 
private int mMessageGetLimit; 

public override void Run() 
{ 
    // Refresh the configuration members only when they change. 
    RoleEnvironment.Changed += RoleEnvironmentChanged; 

    // Initialize them for the first time 
    RefreshRoleEnvironmentSettings(); 

    while (true) 
    { 
     var messages = queue.GetMessages(mMessageGetLimit); 

     if (messages.Count() > 0) 
     { 
      ProcessQueueMessages(messages); 
     } 
     else 
     { 
      Task.Delay(mPollingInterval); 
     } 
    } 
} 

private void RoleEnvironmentChanged(object sender, RoleEnvironmentChangedEventArgs e) 
{ 
    RefreshRoleEnvironmentSettings();  
} 

private void RefreshRoleEnvironmentSettings() 
{ 
    mPollingInterval = TimeSpan.FromSeconds(Convert.ToInt32(RoleEnvironment.GetConfigurationSettingValue("PollingIntervalSeconds"))); 
    mMessageGetLimit = Convert.ToInt32(RoleEnvironment.GetConfigurationSettingValue("MessageGetLimit")); 
} 
3

요한의 대답은 다시 시작하지 않고 설정을 수정/변경 이벤트를 변경 환경을 사용하여 좋은 일이지만, 나는 아마 더 좋은 방법은 당신이 더 폴링을 만들기 위해 지수 백 오프 (back-off) 정책을 사용하는 생각 실력 있는. 코드 동작을 더 스마트하게하면 코드를 수정하는 빈도를 줄일 수 있습니다. 이러한 환경 설정을 업데이트 할 때마다 모든 인스턴스로 롤아웃해야하며 실행중인 인스턴스 수에 따라 약간의 시간이 걸릴 수 있음을 기억하십시오. 또한 인간이 개입해야한다는 단계를 밟고 있습니다.

Windows Azure 저장소 큐를 사용하고있는 것은 GetMessages가 서비스를 호출하고 0 개 이상의 메시지를 검색 할 때마다 (MessageGetLimit까지)를 의미합니다. 매번 거래가 청구될 때마다 요청합니다. 자, 거래가 정말 저렴하다는 것을 이해하십시오. 하루에 10 만 건의 거래도 하루에 0.01 달러입니다. 그러나 루프의 속도를 과소 평가하지 마십시오. :) 당신은 그보다 더 많은 처리량을 얻을 수 있으며 다중 작업자 역할 인스턴스가있는 경우이 인스턴스가 추가됩니다 (인스턴스 자체를 실제로 실행하는 것과 비교하면 여전히 적은 금액 임).

더 효율적인 경로는 대기열에서 메시지를 읽는 지수 백 오프 접근 방식입니다. 간단한 예를 들어 Maarten의이 게시물을 확인하십시오 : http://www.developerfusion.com/article/120619/advanced-scenarios-with-windows-azure-queues/. 대기열 깊이에 따라 작업자 역할을 자동으로 조정하여 접근 방식을 다시 사용하면 사람의 조정 설정에 덜 의존하는 솔루션을 얻을 수 있습니다. 인스턴스 수에 대한 최소값과 최대 값을 입력하고 다음 번에 메시지를 요청할 때 메시지가 몇 번 있었는지에 따라 가져올 메시지 수를 조정하십시오. 여기에는 참여를 줄이는 많은 옵션이 있습니다 효율적인 시스템을 갖추고 있습니다.

또한 Windows Azure 서비스 버스 큐는 긴 폴링을 구현한다는 점에서 볼 때 작업이 대기열에 도달하기를 기다리는 동안 훨씬 적은 트랜잭션이 발생합니다.

+0

실제로 이것을 구현 했으므로 도움보다 많은 문제가 발생했습니다. 대기열을 사용하여 예상되는 지연이 발생하는 미니 작업을 구현했습니다. 불행히도, 폴링을 백 오프 한 상태에서 클라이언트가 30 개의 요청/미니 작업을 한 번에 보낼 수있는 상황이 있었고 한 달에 몇 달러를 절약하기 위해 노력한 페니였습니다. 이러한 요청은 불필요한 임계 값으로 지연되었습니다. –

+0

지연은 메시지 처리를 기다리는 최대 시간입니다. 2 초인 경우 2 초 이상 기다려서는 안됩니다. 시스템은 메시지 처리를 마친 직후에 다시 점검하기 전에 다른 메시지가 있는지 확인해야합니다. 항상 즉각적인 응답을 원하면 긴밀한 루프를 유지하거나 대기열 이외의 것을보십시오. 나는 이것이 어떤 경우에 두려워 할 수 있다는 것에 동의 할 것이지만 인간의 개입을 정기적으로 요구하는 것을 넣는 것도 좋지 않다. 결국 더 많은 비용이 들게 될 것입니다. – MikeWo