[英]Can we use Polly retry instead of ExponentialBackoffRetry in Service Bus Topic Trigger Azure Function?
我们正在使用服务总线主题触发器 Azure 函数,并且我们计划在 Azure 函数中实现一个简单的行为,如果在处理/处理过程中出现任何异常,我们希望将下一次重试推迟一段时间。
目前我们计划使用[ExponentialBackoffRetry]
属性,如下面的代码所示。
但是我们可以使用Polly retry 代替[ExponentialBackoffRetry]
吗? 基本上哪种方法可以满足我们的要求 - [ExponentialBackoffRetry]
或Polly重试
下面是我们的服务总线主题触发 Azure 函数:
[FunctionName(nameof(CardGroupEventSubscriber))]
[ExponentialBackoffRetry(5, "00:00:04", "00:01:00")]
public async Task RunAsync([ServiceBusTrigger("%ServiceBusConfigOptions:TopicEventTypeName%", "%ServiceBusConfigOptions:TopicEventTypeSubscription%",
Connection = "ServiceBusConfigOptions:ConnectionString")]
string sbMsg)
{
try
{
var message = sbMsg.AsPoco<CardGroupEvent>();
_logger.LogInformation("{class} - {method} - {RequestId} - Start",
nameof(CardGroupEventSubscriber), nameof(CardGroupEventSubscriber.RunAsync), message.RequestID);
_logger.LogInformation($"Started processing message {message.AsJson()} with", nameof(CardGroupEventSubscriber));
var validationResult = new CardGroupEventValidator().Validate(message);
if (validationResult.IsValid)
{
await _processor.ProcessAsync(message);
}
catch (Exception ex)
{
_logger.LogError($"Unable to process card group event {sbMsg.AsJson()} with {nameof(CardGroupEventSubscriber)}," +
$" ExceptionMessage:{ex.Message}, StackTrace: {ex.StackTrace}");
throw;
}
#endregion
}
Polly 的策略可以以命令的方式定义和使用。
而ExponentialBackoffRetry
属性可以被认为是声明性的。
因此,假设您要定义一个策略
CosmosException
时,您才可以这样做:const int maxRetryAttempts = 10;
const int maxDelayInMilliseconds = 32 * 1000;
var jitterer = new Random();
var policy = Policy
.Handle<CosmosException>()
.WaitAndRetryAsync(
maxRetryAttempts,
retryAttempt =>
{
var calculatedDelayInMilliseconds = Math.Pow(2, retryAttempt) * 1000;
var jitterInMilliseconds = jitterer.Next(0, 1000);
var actualDelay = Math.Min(calculatedDelayInMilliseconds + jitterInMilliseconds, maxDelayInMilliseconds);
return TimeSpan.FromMilliseconds(actualDelay);
}
);
Polly.Contrib.WaitAndRetry
) 现在让我们将其应用于您的RunAsync
方法
[FunctionName(nameof(CardGroupEventSubscriber))]
public async Task RunAsync([ServiceBusTrigger("%ServiceBusConfigOptions:TopicEventTypeName%", "%ServiceBusConfigOptions:TopicEventTypeSubscription%",
Connection = "ServiceBusConfigOptions:ConnectionString")]
string sbMsg)
=> await GetExponentialBackoffRetryPolicy.ExecuteAsync(
async () => await RunCoreAsync(sbMsg));
public async Task RunCoreAsync(string sbMsg)
{
try
...
}
RunAsync
的代码移动到RunCoreAsync
方法中RunAsync
实现替换为一个创建上述策略然后装饰RunCoreAsync
附带说明:在 CosmosDb 的情况下,以不同的方式处理速率限制/节流可能是有意义的。
当我收到CosmosException
并且StatusCode
是 429 然后使用RetryAfter
的值来延迟重试,就像这样
var policy = Policy
.Handle<CosmosException>(ex => ex.StatusCode == HttpStatusCode.TooManyRequests)
.WaitAndRetryAsync(maxRetryAttempts,
sleepDurationProvider:(_, ex, __) => ((CosmosException)ex).RetryAfter.Value,
onRetryAsync: (_, __, ___, ____) => Task.CompletedTask);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.