[英]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.