2013-07-22 46 views
3

我調用client.Send(brokeredMessage);一次,但我多次收到消息。對於手柄隊列我使用此代碼Azure ServiceBus隊列。我多次收到相同的消息

private static void HandleQueue(string queueName, MessageHandler messageHandler) 
     { 
      // Create the queue if it does not exist already 
      string connectionString = 
       Configuration.GetConnectionString("Microsoft.ServiceBus.ConnectionString",false); 

      var namespaceManager = 
       NamespaceManager.CreateFromConnectionString(connectionString); 

      if (!namespaceManager.QueueExists(queueName)) 
      { 
       namespaceManager.CreateQueue(queueName); 
      } 

      QueueClient client = 
       QueueClient.CreateFromConnectionString(connectionString, queueName); 

      while (true) 
      { 
       BrokeredMessage message = client.Receive(); 

       if (message != null) 
       { 
        try 
        {  
         messageHandler(message); 

         // Remove message from queue 
         message.Complete(); 
        } 
        catch (Exception) 
        { 
         // Indicate a problem, unlock message in queue 
         message.Abandon(); 
        } 
       } 
      } 
     } 

問題是,BrokeredMessage message = client.Receive();被調用幾次,返回相同的消息,如果messageHandler(message);執行需要很長時間。我該如何解決它?

回答

11

該消息,而你的處理是越來越解鎖再次出現。設置鎖超時消息的正確的地方是在QueueDescriptionhttp://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.queuedescription.lockduration.aspx

這裏允許的最大時間是5分鐘,所以如果你需要處理更長時間則消息,你可以調用RenewLock上的消息繼續讓其他消費者不能看到它。在你完成處理之前調用Complete是正確的,因爲如果你處理崩潰,那麼你不會再收到消息。

BrokeredMessage.ScheduledEnqueueTimeUtc的上述屬性用於在消息從隊列中顯示給消費者時「延遲」。假設您在第1天發送消息,並將預定時間設置爲第2天,則消息將不會由Recieve呼叫返回,直到第2天。

+0

5分鐘後,如果嘗試更新鎖,則表示鎖已過期消息! – Rusty

+0

鎖定時間到期後我不能更新鎖嗎?例如5分鐘後如果嘗試更新鎖,則表示鎖定已過期! – Rusty

+1

@Rusty:您需要更新鎖_before_過期。如果鎖在五分鐘內過期,請提前10秒更新。您可以重複更新。 –

1

有你應該做的幾件事情:

  1. 你雖然(真)環路中引入的睡眠時間。可以說,Thread.Sleep(30000);
  2. 檢索郵件內容並將郵件標記爲完整。然後將檢索到的內容傳遞給消息處理程序,而不是消息本身。等待完成「messagehanfler」並不是一個好習慣。
  3. 如果在處理過程中您的消息處理程序中發生錯誤,請將具有相同內容的另一個代理消息進行排隊。
  4. 處理有毒消息。檢查每個代理消息的交付計數,並在交付次數超過n次時刪除消息,例如5次。

希望它有幫助!

+1

我不認爲1分是好主意。在messageHandler(消息)之前執行message.Complete()可以提供幫助,但它不能解決多次刪除問題的問題。在我的情況下,如果你的意思是交付計數是對象類型BrokeredMessage的屬性,它始終等於1. –

1

聽起來像你的消息回到隊列,如果它沒有在允許的時間內處理(根據你的描述,它只發生在messageHandler運行很長時間時)。

聽起來就像你想提高你的消息的可見性超時,以便他們不會很快回到隊列安靜。與ServiceBus這意味着預先計算的消息時的時間,如果它未完成

http://msdn.microsoft.com/en-us/library/microsoft.servicebus.messaging.brokeredmessage.scheduledenqueuetimeutc.aspx

+0

我可以爲BrokeredMessage.ScheduledEnqueueTimeUtc設置DateTime.MaxValue以避免消息返回隊列或以某種方式標記它嗎? –

相關問題