我有一个场景,我在我的一个处理程序中调用一个api,而Api可能每个月停机6个小时。因此,我设计了一个重试逻辑,包括1秒重试、1分钟重试和6小时重试。这一切都很好,但后来我发现,长时间延迟重试不是一个好的option.Could,你能告诉我你的经验吗?
谢谢!
发布于 2017-07-28 18:25:09
如果我是你,我会利用Rebus的能力将消息推迟到未来来实现这一功能。
但是,您需要手动跟踪失败的传递尝试的次数,方法是附加和更新延迟邮件的标头。
下面这样的代码应该能起到作用:
public class YourHandler : IHandleMessages<MakeExternalApiCall>
{
const string DeliveryAttemptHeaderKey = "delivery-attempt";
public YourHandler(IMessageContext context, IBus bus)
{
_context = context;
_bus = bus;
}
public async Task Handle(MakeExternalApiCall message)
{
try
{
await MakeCallToExternalWebApi();
}
catch(Exception exception)
{
var deliveryAttempt = GetDeliveryAttempt();
if (deliveryAttempt > 5)
{
await _bus.Advanced.TransportMessage.Forward("error");
}
else
{
var delay = GetNextDelay(deliveryAttempt);
var headers = new Dictionary<string, string> {
{DeliveryAttemptHeaderKey, (deliveryAttempt+1).ToString()}
};
await bus.Defer(delay.Value, message, headers);
}
}
}
int GetDeliveryAttempt() => _context.Headers.TryGetValue(DeliveryAttemptHeaderKey, out var deliveryAttempt)
? deliveryAttempt
: 0;
TimeSpan GetNextDelay() => ...
}
在生产环境中运行时,请记住配置某种持久订阅存储- e.g。SQL Server -否则,您的延迟消息将在重新启动时丢失。
您可以这样配置它(在安装了Rebus.SqlServer
包之后):
Configure.With(...)
.(...)
.Timeouts(t => t.StoreInSqlServer(...))
.Start();
https://stackoverflow.com/questions/45369689
复制相似问题