2016-07-17 166 views
4

我正在嘗試使用Azure服務總線來提高Windows服務的吞吐量。我注意到的是,如果我有這樣的代碼。Azure服務總線讀取性能

client.OnMessageAsync(async message => 
      { 
       var timer = new Stopwatch(); 
       timer.Start(); 
       bool shouldAbandon = false; 
       try 
       { 
        // asynchronouse processing of messages 
        await messageProcessor.ProcessAsync(message); 
        Interlocked.Increment(ref SimpleCounter); 
        // complete if successful processing 
        await message.CompleteAsync(); 
       } 
       catch (Exception ex) 
       { 
        shouldAbandon = true; 
        Console.WriteLine(ex); 
       } 

       if (shouldAbandon) 
       { 
        await message.AbandonAsync(); 
       } 
       timer.Stop(); 
       messageTimes.Add(timer.ElapsedMilliseconds); 
      }, 
      options); 

如果選項是

OnMessageOptions options = new OnMessageOptions 
      { 
       MaxConcurrentCalls = maxConcurrent, 
       AutoComplete = false 
      }; 

增加MaxConcurrentCalls具有一定的次數後影響不大(12-16通常是我在做什麼)。

但使用相同的MaxConcurrentCalls創建多個客戶端(QueueClient)確實會提高性能(幾乎線性)。

所以我一直在做的是使#queueclient和maxconcurrentcalls可配置,但我想知道是否有多個隊列客戶端是最好的方法。

所以我的問題是:有多個queuepients與messagepumps運行糟糕或良好的做法的Windows服務和天藍色的服務總線?

+0

服務器上有多少核心?你所有的Windows服務實例都將在同一臺服務器上運行?否則,創建多個工作者而不是多個線程來增加隊列的吞吐量並不是一個壞習慣。擴大總是一個解決方案^^ – Thomas

+0

4核心。每個服務器的單個實例是最初的目標(共有5-7個服務器)。我期望從單個實例中獲得最大收益(我可以安裝多個實例並獲得我相信的類似結果) – Josh

回答

0

我知道現在真的很老了 - 但我想我會貢獻自己的發現。

僅僅通過在同一臺機器上運行多個進程,我看到了隊列處理性能的提高。在我的情況下,我使用控制檯應用程序,但原理是相同的。我認爲最終這是因爲MaxConcurrency值最終控制着服務總線將多少消息傳遞給一個消費客戶端 - 當它達到該限制時,它會有效地進入休眠狀態一段時間(大約1秒鐘體驗),然後嘗試推送更多的消息。

因此,如果您有一個非常簡單的消息處理程序,即使將MaxConcurrency設置爲邏輯核心數的2倍/ 3倍/ 4倍,但即使您將處理多個消息的速度仍然很慢推送比客戶端配置爲一次處理更多的消息。使用相同的MaxConcurrency運行另一個流程可以提供兩倍的可用容量 - 即使在同一臺機器上 - 但實際上並沒有提供更多功率。

最終,正確的配置將取決於您的隊列任務的處理器使用情況配置文件。如果它們長時間運行並傾向於啃過處理器週期,那麼太大的速度可能會讓你放慢速度,而不是放慢速度 - 而且擴展到其他機器真的是唯一的解決方案。

但是,如果您的隊列任務是「稀疏」並且大部分時間都在等待,那麼您將能夠脫離更高的MaxConcurrency而不是處理器中的邏輯內核 - 因爲它們不會全部一直很忙。