使用 Rabbitmq 在 Rebus 中进行二级重试
Second level retries in Rebus with Rabbitmq
我有一个场景,我在我的一个处理程序中调用 api,Api 每个月可能会停机 6 个小时。因此,我设计了1秒重试、1分钟重试和6小时重试的重试逻辑。这一切都很好,但后来我发现长时间延迟重试不是一件好事 option.Could 请告诉我你对此的经验?
谢谢!
如果我是你,我会使用 Rebus 将消息延迟到未来的能力来实现此功能。
不过,您需要通过在延迟邮件上附加和更新 headers 来手动跟踪失败的投递尝试次数。
像这样应该可以解决问题:
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() => ...
}
当 运行 投入生产时,请记住配置某种持久订阅存储 – 例如SQL 服务器 – 否则,您的延迟消息将在重新启动时丢失。
你可以像这样配置它(在安装了 Rebus.SqlServer
包之后):
Configure.With(...)
.(...)
.Timeouts(t => t.StoreInSqlServer(...))
.Start();
我有一个场景,我在我的一个处理程序中调用 api,Api 每个月可能会停机 6 个小时。因此,我设计了1秒重试、1分钟重试和6小时重试的重试逻辑。这一切都很好,但后来我发现长时间延迟重试不是一件好事 option.Could 请告诉我你对此的经验?
谢谢!
如果我是你,我会使用 Rebus 将消息延迟到未来的能力来实现此功能。
不过,您需要通过在延迟邮件上附加和更新 headers 来手动跟踪失败的投递尝试次数。
像这样应该可以解决问题:
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() => ...
}
当 运行 投入生产时,请记住配置某种持久订阅存储 – 例如SQL 服务器 – 否则,您的延迟消息将在重新启动时丢失。
你可以像这样配置它(在安装了 Rebus.SqlServer
包之后):
Configure.With(...)
.(...)
.Timeouts(t => t.StoreInSqlServer(...))
.Start();