2017-08-11 142 views
0

Im構建隊列處理webjob以從隊列中讀取消息並使用數據從blob存儲中檢索報告uri,然後將其作爲電子郵件中的鏈接發送。我的流程工作得很好,但我需要在特定的時間窗口內發送電子郵件。azure隊列存儲 - 將消息放回隊列

我有另一個進程(webjob)從sql後端檢索這些數據並將其放入電子郵件隊列中。

此webjob每30分鐘運行一次,並且只獲取當前時間和當前時間的2小時窗口內的數據。所以我知道排隊中的任何事情都是在今天和現在的2小時之內。我如何進一步縮小這個範圍以便從隊列中讀取數據,並且如果「發送電子郵件」時間設置爲19:00,當前時間爲18:00,則可以將該消息放回隊列中讀取再後來,下一次應該更接近19:00,然後我可以處理它並通過電子郵件發送出去。
時間不一定要被發現,所以即使它在19點30分鐘內(或者它的任何發送時間)也可以被處理。所以我有效地從隊列中取出一個對象,檢查它的時間,並且如果它不在其分配的「電子郵件輸出」時間的30分鐘內,我將它放回隊列中並且再次處理

**在我的webjob ,我有一個'Functions'類,它包含一個方法'ProcessQueueMessage',每當一個消息被放入隊列時它就會被觸發。

// This function will get triggered/executed when a new message is written 
    // on an Azure Queue called queue. 
    public async Task ProcessQueueMessage([QueueTrigger("%reportgenerator%")] Data.Dto.Schedule.ScheduleDto schedule) 
    { 
     var reports = await this._scheduledReportGenerationService.GenerateScheduledEmails(schedule.ID); 
    } 

的ScheduleDto類將有一代人的時間屬性,我可以讀這一點,它比較當前時間和僅在處理它的我指定的「時間窗口」內。我將如何停止隊列消息在這裏被刪除,以便我可以重新處理它?

+0

您使用的是Azure存儲隊列還是服務總線隊列? –

+1

另外,從您的問題來看,如果您使用2個webjobs或者只有1個webjob,則不清楚。一個小問題:請花一點時間,格式化你的問題,並在段落中分解。閱讀一個大的大段落是一個痛苦:)。 –

+0

我有2個webjobs,一個從後臺獲取'今天2小時內'的數據,創建指定的報告並將其放入blob存儲中。另一個讀取這些數據,並通過電子郵件發送blob(pdf)的URI。我使用Azure存儲隊列 – proteus

回答

1

當您將消息添加到隊列中時,只需設置initialVisibilityDelay,以便消息在最小處理時間之前才能看到。

CloudQueue queue = queueClient.GetQueueReference(queueName); 
var msg = new CloudQueueMessage("Hello World!"); 
TimeSpan timeSpanDelay = GetEarliestProcessTime(); 
await queue.AddMessageAsync(msg, null, timeSpanDelay, null, null); 

CloudQueue.AddMessage

1

因此,有是與Azure存儲隊列幾件事情,是要幫助你與這樣的場景:

關於把消息發回隊列中,你沒有做什麼特別的。這是由存儲隊列提供的功能。當您將郵件出隊(Azure存儲術語中的GET Message)時,郵件在一段時間內變得不可見,如果未被出隊郵件的進程刪除,郵件將再次變爲可見,並可被另一個進程拾取。

因此,當您將郵件出列時,請檢查時間,如果時間不正確,您什麼都不做。但是,請確保一旦處理完消息,您將刪除該消息,否則將會再次提取消息。

您可以做的另一件事是當您將郵件出列並且發現它不是處理該郵件的正確時間時,您更新該郵件並將其可見性超時屬性設置爲使該郵件再次可見的值接近處理時間。例如,您在18:00出列消息,發現此消息需要在19:00處理。在這種情況下,您將更新郵件並將其可見性超時設置爲50分鐘(或30分鐘以上的值爲Web作業的計劃)。這將確保當你的webjob在18:30運行時,這個消息不會被web作業拾取,因爲這個消息只會在18:50顯示。

您可以在這裏閱讀有關更新消息的更多信息:https://docs.microsoft.com/en-us/rest/api/storageservices/update-message以及關於在此處列出消息的信息:https://docs.microsoft.com/en-us/rest/api/storageservices/get-messages

更新

我完全忘了這是在WebJob所以什麼都不做實際上將刪除該郵件。我猜你有兩種選擇(重複評論中提到的那種):

  1. 拋出異常而不是無所事事。這將確保WebJob處理器不會刪除該消息。我沒有自己嘗試過,但是您也可以更新消息並將其可見性超時設置爲更接近WebJob本身所需時間的值(然後引發異常)。不過這是一種反模式。
  2. 您在隊列中添加一條新消息,並將其初始可見性超時值設置爲接近所需時間的值(這也在另一個答案中涵蓋),並且刪除此消息。
+0

我還沒有實際使用GetMessage讀取隊列消息,在我的WebJob中,我有host.RunAndBlock,然後在我的函數類中我有一個方法(ProcessQueueMessage)這就是無論何時將新消息寫入到隊列中,都會觸發,這是'默認'webjob行爲。這不是最佳做法嗎? – proteus

+0

閱讀和刪除(以及放入毒隊)所有似乎都是自動發生的,沒有任何我的干預,我只是在處理消息時才檢測到它 – proteus

+0

@proteus:你說得對,WebJobs下的消息自動刪除時函數正常完成。 Gaurav表示相反,也許他熟悉較低級別的Queue Storage API。 – camelCase

1

當EN-隊列Azure存儲隊列中的項目,你可以添加額外的細節,這將導致該項目被隱藏了配置的持續時間的項目。如果您的批處理作業只能每兩小時運行一次,但您希望延遲發送更精細時間控制的電子郵件,那麼我建議兩小時連續批處理作業可以使用此「initialVisibilityDelay」功能。

這是另一個SO問題,描述了API。

Azure storage queue message (show at specific time)