Refit ApiException 的最佳重试策略?
Best retry policy for Refit ApiException?
我正在使用 Refit 和 Polly 来调用 restful API 和我我想知道 Refits ApiException 的重试(如果有的话)策略应该是什么?
public static PolicyWrap MyRetryPolicy()
{
// Try few times with little more time between... maybe the
// connection issue gets resolved
var wireServerNetworkIssue = Policy.Handle<WebException>()
.WaitAndRetryAsync(new[] {
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(4)});
var policyList = new List<Policy>();
// But if there is something wrong with the api
// I should do what (if general)?
var api = Policy.Handle<ApiException>()
.RetryAsync(1, onRetry: async (exception, i) =>
{
await Task.Run(() =>
{
// What would be normal to do here?
// Try again or do some circuit braking?
});
});
policyList.Add(wireServerNetworkIssue);
policyList.Add(api);
return Policy.Wrap(policyList.ToArray());
}
然后我就这样使用它
try
{
myApi = RestService.For<MyApi>("api base url");
var policyWrapper = Policies.Policies.MyRetryPolicyWrapper();
var response = await policy.ExecuteAsync(() => myApi.SendReceiptAsync(receipt));
}
catch (ApiException apiEx)
{
//Do something if the retry policy did´t fix it.
}
catch (WebException webEx)
{
//Do something if the retry policy did´t fix it.
}
问题
ApiExceptions的正常重试策略是什么?你会只是电路制动还是在什么一般情况下你会做些什么来恢复?
答案可能是"it depends on what your service returns",但我不得不问。
如果返回的 ApiException
包含有意义的 HttpStatusCode StatusCode
properties, you could certainly choose which of those StatusCodes merit a retry; the Polly readme 建议:
int[] httpStatusCodesWorthRetrying = {408, 500, 502, 503, 504};
对于特定于 API 调用的 ApiException
,只有了解那些特定于 API 的错误代表什么,才能指导是否重试它们。
如果您选择对某种类型的太多异常进行熔断,那应该通过将熔断器包装到您的 PolicyWrap
, rather than within the onRetry
delegate of the retry policy. Polly discusses 'Why circuit-break?' here, and links to a number of other circuit-breaker blog posts at the foot of the readme circuit-breaker section.
中来实现
我正在使用 Refit 和 Polly 来调用 restful API 和我我想知道 Refits ApiException 的重试(如果有的话)策略应该是什么?
public static PolicyWrap MyRetryPolicy()
{
// Try few times with little more time between... maybe the
// connection issue gets resolved
var wireServerNetworkIssue = Policy.Handle<WebException>()
.WaitAndRetryAsync(new[] {
TimeSpan.FromSeconds(1),
TimeSpan.FromSeconds(2),
TimeSpan.FromSeconds(4)});
var policyList = new List<Policy>();
// But if there is something wrong with the api
// I should do what (if general)?
var api = Policy.Handle<ApiException>()
.RetryAsync(1, onRetry: async (exception, i) =>
{
await Task.Run(() =>
{
// What would be normal to do here?
// Try again or do some circuit braking?
});
});
policyList.Add(wireServerNetworkIssue);
policyList.Add(api);
return Policy.Wrap(policyList.ToArray());
}
然后我就这样使用它
try
{
myApi = RestService.For<MyApi>("api base url");
var policyWrapper = Policies.Policies.MyRetryPolicyWrapper();
var response = await policy.ExecuteAsync(() => myApi.SendReceiptAsync(receipt));
}
catch (ApiException apiEx)
{
//Do something if the retry policy did´t fix it.
}
catch (WebException webEx)
{
//Do something if the retry policy did´t fix it.
}
问题
ApiExceptions的正常重试策略是什么?你会只是电路制动还是在什么一般情况下你会做些什么来恢复?
答案可能是"it depends on what your service returns",但我不得不问。
如果返回的 ApiException
包含有意义的 HttpStatusCode StatusCode
properties, you could certainly choose which of those StatusCodes merit a retry; the Polly readme 建议:
int[] httpStatusCodesWorthRetrying = {408, 500, 502, 503, 504};
对于特定于 API 调用的 ApiException
,只有了解那些特定于 API 的错误代表什么,才能指导是否重试它们。
如果您选择对某种类型的太多异常进行熔断,那应该通过将熔断器包装到您的 PolicyWrap
, rather than within the onRetry
delegate of the retry policy. Polly discusses 'Why circuit-break?' here, and links to a number of other circuit-breaker blog posts at the foot of the readme circuit-breaker section.