1
我有一個場景,我在我的一個處理程序中調用api,並且Api可以每個月減少6小時。因此,我設計了1秒重試,1分鐘重試和6小時重試的重試邏輯。這一切工作正常,但後來我發現長時間延遲重試不是一個好的選擇。請給我你的經驗嗎?Rebus與Rabbitmq的二級重試
謝謝!
我有一個場景,我在我的一個處理程序中調用api,並且Api可以每個月減少6小時。因此,我設計了1秒重試,1分鐘重試和6小時重試的重試邏輯。這一切工作正常,但後來我發現長時間延遲重試不是一個好的選擇。請給我你的經驗嗎?Rebus與Rabbitmq的二級重試
謝謝!
如果我是你,我會使用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() => ...
}
當在生產環境中運行,請記得要配置一些形式的持久訂閱存儲 - 例如SQL Server - 否則,如果重新啓動,您的延期郵件將會丟失。
可以這樣配置它(已安裝Rebus.SqlServer
包後):
Configure.With(...)
.(...)
.Timeouts(t => t.StoreInSqlServer(...))
.Start();
我能得到這個工作,而注入的消息上下文,但使用MessageContext.Current.Header。但現在我需要編寫一個採用假總線的單元測試,並驗證不同的消息在總線上。爲此我需要注入消息上下文並使用你的方法。你能告訴我如何使用autofac注入消息上下文嗎? –
如果你使用的是官方的Rebus.Autofac軟件包,注入'IMessageContext'已經自動配置 - 所以你可以在你的處理程序中添加'IMessageContext messageContext'作爲ctor參數,然後它應該可以工作 – mookid8000
非常感謝! –