C# Azure函数:如何更好地实现重试队列消息的延迟
My Azure函数应该侦听队列中的消息,然后获取消息,尝试调用消息中包含值的外部服务,如果外部服务返回“OK”,则我们必须将消息写入另一个队列(对于下一个Azure函数),如果返回“Fail”我们必须返回到当前队列,并在5分钟后通过Azure函数再次重试。如何实施?我是用定时器完成的,但解决方案不喜欢我:C# Azure函数:如何更好地实现重试队列消息的延迟,c#,azure,azure-functions,azure-queues,C#,Azure,Azure Functions,Azure Queues,My Azure函数应该侦听队列中的消息,然后获取消息,尝试调用消息中包含值的外部服务,如果外部服务返回“OK”,则我们必须将消息写入另一个队列(对于下一个Azure函数),如果返回“Fail”我们必须返回到当前队列,并在5分钟后通过Azure函数再次重试。如何实施?我是用定时器完成的,但解决方案不喜欢我: [FunctionName("FunctionOffice365VerificateDomain_and_AddService_and_GexMxRecord")] publ
[FunctionName("FunctionOffice365VerificateDomain_and_AddService_and_GexMxRecord")]
public async static Task Run([TimerTrigger("0 */5 * * * *")]TimerInfo myTimer,
[Queue("domain-verificate-Office365-add-services-get-mx-record", Connection = "StorageConnectionString")]CloudQueue listenQueue,
[Queue("domain-add-mx-record-to-registrator", Connection = "StorageConnectionString")]CloudQueue outputQueue,
ILogger log)
{
while (true)
{
// do "invisible" message for next 30 sec
var message = await listenQueue.GetMessageAsync();
if (message != null)
{
DomainForRegistration domainForRegistration = JsonConvert.DeserializeObject<DomainForRegistration>(message.AsString);
try
{
await _office365DomainService.VerifyDomainAsync(domainForRegistration.DomainName);
// remove message
await listenQueue.DeleteMessageAsync(message);
await _office365DomainService.UpdateIndicateSupportedServicesDomainAsync(domainForRegistration.DomainName);
var mxRecord = await _office365DomainService.GetMxRecordForDomainAsync(domainForRegistration.DomainName);
}
catch (DomainVerificationRecordNotFoundException)
{
// thrown when VerifyDomainAsync failed
}
}
else
break;
}
}
[FunctionName(“FunctionOffice365VerificateDomain”和“添加服务”和“GexMxRecord”)]
公共异步静态任务运行([TimerTrigger(“0*/5****”)TimerInfo myTimer,
[Queue(“domain-verificate-Office365-add-services-get-mx-record”,Connection=“StorageConnectionString”)]CloudQueue listenQueue,
[Queue(“域将mx记录添加到注册器”,Connection=“StorageConnectionString”)]CloudQueue outputQueue,
ILogger日志)
{
while(true)
{
//在接下来的30秒内执行“不可见”消息
var message=await listenQueue.GetMessageAsync();
如果(消息!=null)
{
DomainForRegistration DomainForRegistration=JsonConvert.DeserializeObject(message.AsString);
尝试
{
wait_office365DomainService.VerifyDomainAsync(domainForRegistration.DomainName);
//删除消息
wait listenQueue.DeleteMessageAsync(消息);
wait_office365; domainservice.updateIndicatedSupportedServicesDomainAsync(domainForRegistration.DomainName);
var mxRecord=wait_office365DomainService.GetMxRecordForDomainAsync(domainForRegistration.DomainName);
}
捕获(DomainVerificationRecordNotFoundException)
{
//VerifyDomainAsync失败时引发
}
}
其他的
打破
}
}
如何更仔细地执行此操作,而不使用这些
(true)
,而是在验证失败后超时?同意@DavidG,尝试使用队列触发器来实现您的目标。
W可以依赖于队列的长度
visibilityTimeout是消息处理失败时重试之间的时间间隔
maxDequeueCount是将消息移动到毒药队列之前尝试处理消息的次数
这样,函数应该如下所示
public static async Task Run(
[QueueTrigger("domain-verificate-Office365-add-services-get-mx-record")]string myQueueItem, ILogger log,
[Queue("domain-add-mx-record-to-registrator", Connection = "StorageConnectionString")]IAsyncCollector<string> outputQueue
)
{
// do stuff then output message
await outputQueue.AddAsync(myQueueItem);
}
公共静态异步任务运行(
[QueueTrigger(“domain-verificate-Office365-add-services-get-mx-record”)]字符串myQueueItem,ILogger日志,
[队列(“域将mx记录添加到注册器”,Connection=“StorageConnectionString”)]IAsyncCollector输出队列
)
{
//做一些事情然后输出消息
等待outputQueue.AddAsync(myQueueItem);
}
如果您不想将异常抛出到主机,我们可以使用CloudQueue方法
指定从现在起消息不可见的时间间隔
公共静态异步任务运行(
[QueueTrigger(“domain-verificate-Office365-add-services-get-mx-record”)]字符串myQueueItem,ILogger日志,
[队列(“域将mx记录添加到注册器”,Connection=“StorageConnectionString”)]IAsyncCollector输出队列,
[Queue(“domain-verificate-Office365-add-services-get-mx-record”,Connection=“StorageConnectionString”)]CloudQueue listenQueue
)
{
尝试
{
//做一些事情然后输出消息
等待outputQueue.AddAsync(myQueueItem);
}
捕获(DomainVerificationRecordNotFoundException)
{
//将消息添加到当前队列中,并且仅在5分钟后可见
wait listenQueue.AddMessageAsync(新的CloudQueueMessage(myQueueItem)),null,TimeSpan.FromMinutes(5),null,null;
}
}
如果这是一个队列,为什么不为每条消息触发该函数?不确定为什么需要循环。@DavidG,因为失败后我必须添加相同的消息,函数将立即(毫不延迟)再次调用谢谢!我不知道将消息添加到队列的“延迟”参数:)
public static async Task Run(
[QueueTrigger("domain-verificate-Office365-add-services-get-mx-record")]string myQueueItem, ILogger log,
[Queue("domain-add-mx-record-to-registrator", Connection = "StorageConnectionString")]IAsyncCollector<string> outputQueue
)
{
// do stuff then output message
await outputQueue.AddAsync(myQueueItem);
}
public static async Task Run(
[QueueTrigger("domain-verificate-Office365-add-services-get-mx-record")]string myQueueItem, ILogger log,
[Queue("domain-add-mx-record-to-registrator", Connection = "StorageConnectionString")]IAsyncCollector<string> outputQueue,
[Queue("domain-verificate-Office365-add-services-get-mx-record", Connection = "StorageConnectionString")]CloudQueue listenQueue
)
{
try
{
// do stuff then output message
await outputQueue.AddAsync(myQueueItem);
}
catch(DomainVerificationRecordNotFoundException)
{
// add the message in current queue and can only be visible after 5 minutes
await listenQueue.AddMessageAsync(new CloudQueueMessage(myQueueItem), null, TimeSpan.FromMinutes(5), null, null);
}
}