[英]In queue-triggered Azure Webjobs can an Azure Storage Queue message be modified after webjob function failure but before poisoning?
我的Azure webjobs中有隊列觸發的功能。 正常行為當然是當函數失敗時, MaxDequeueCount
次將消息放入相應的毒性隊列。 我想在錯誤發生后 ,但有害隊列插入之前修改的消息。 例:
初步訊息:
{ "Name":"Tom", "Age", 30" }
失敗后,我想按如下方式修改消息,並將修改后的消息插入到毒性隊列中:
{ "Name":"Tom", "Age", 30", "ErrorMessage":"Unable to find user" }
可以這樣做嗎?
根據Webjobs文檔,在5次嘗試處理消息失敗后,消息將被置於毒性隊列中:
SDK將最多調用一次函數5次來處理隊列消息。 如果第五次嘗試失敗,則將消息移動到毒性隊列。 最大重試次數是可配置的。
資料來源: https : //github.com/Azure/azure-webjobs-sdk/wiki/Queues#poison
這是自動行為。 但是您仍然可以處理WebJobs函數代碼中的異常(因此異常不會使您的函數和自動毒害消息處理不被觸發)並使用輸出綁定將修改后的消息放入毒性隊列。
另一種選擇是檢查dequeueCount屬性,該屬性指示嘗試處理消息的次數。
您可以通過向函數添加名為dequeueCount的int參數來獲取已獲取消息以進行處理的次數。 然后,您可以檢查功能代碼中的出隊計數,並在數量超過閾值時執行自己的有害消息處理,如以下示例所示。
public static void CopyBlob(
[QueueTrigger("copyblobqueue")] string blobName, int dequeueCount,
[Blob("textblobs/{queueTrigger}", FileAccess.Read)] Stream blobInput,
[Blob("textblobs/{queueTrigger}-new", FileAccess.Write)] Stream blobOutput,
TextWriter logger)
{
if (dequeueCount > 3)
{
logger.WriteLine("Failed to copy blob, name=" + blobName);
}
else
{
blobInput.CopyTo(blobOutput, 4096);
}
}
(也取自上面的鏈接)。
您的功能簽名可能如下所示
public static void ProcessQueueMessage(
[QueueTrigger("myqueue")] CloudQueueMessage message,
[Queue("myqueue-poison")] CloudQueueMessage poisonMessage,
TextWriter logger)
默認的最大重試時間是5.您還可以使用JobHostConfiguration()
實例的JobHostConfiguration()
屬性Queues.MaxDequeueCount
設置此值,代碼如下所示:
static void Main(string[] args)
{
var config = new JobHostConfiguration();
config.Queues.MaxDequeueCount = 5; // set the maximum retry time
var host = new JobHost(config);
host.RunAndBlock();
}
然后,您可以在達到最大重試時間時更新失敗的隊列消息。 您可以指定不存在的Blob容器來強制執行重試機制。 代碼如下:
public static void ProcessQueueMessage([QueueTrigger("queue")] CloudQueueMessage message, [Blob("container/{queueTrigger}", FileAccess.Read)] Stream myBlob, ILogger logger)
{
string yourUpdatedString = "ErrorMessage" + ":" + "Unable to find user";
string str1 = message.AsString;
if (message.DequeueCount == 5) // here, the maximum retry time is set to 5
{
message.SetMessageContent(str1.Replace("}", "," + yourUpdatedString + "}")); // modify the failed message here
}
logger.LogInformation($"Blob name:{message} \n Size: {myBlob.Length} bytes");
}
完成上述操作后,您可以在queue-poison中看到更新的隊列消息。
更新:
由於CloudQueueMessage是一個密封類,我們無法繼承它。
對於MySpecialPoco消息,您可以使用JsonConvert.SerializeObject(消息),代碼如下:
using Newtonsoft.Json;
static int number = 0;
public static void ProcessQueueMessage([QueueTrigger("queue")] object message, [Blob("container/{queueTrigger}", FileAccess.Read)] Stream myBlob, ILogger logger)
{
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
CloudQueueClient queueClient = storageAccount.CreateCloudQueueClient();
CloudQueue queue = queueClient.GetQueueReference("queue-poison");// get the poison queue
CloudQueueMessage msg1 = new CloudQueueMessage(JsonConvert.SerializeObject(message));
number++;
string yourUpdatedString = "\"ErrorMessage\"" + ":" + "\"Unable to find user\"";
string str1 = msg1.AsString;
if (number == 5)
{
msg1.SetMessageContent(str1.Replace("}", "," + yourUpdatedString + "}"));
queue.AddMessage(msg1);
number = 0;
}
logger.LogInformation($"Blob name:{message} \n Size: {myBlob.Length} bytes");
}
但不好的是,原始/更新的隊列消息都被寫入毒性隊列。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.