#rabbitmq #masstransit
#rabbitmq #masstransit
Вопрос:
Я хочу две отдельные политики повторных попыток для конкретного потребителя. Одна для HttpRequestException
и SocketException
, а другая для пользовательского DatabaseException
и необработанного SqlException
. Я хочу сделать это, потому что я хочу иметь отдельные экспоненциальные интервалы повторных попыток для обоих.
У меня следующая конфигурация:
cfg.ReceiveEndpoint(
host,
"ExampleQueueName",
ec =>
{
ec.Consumer<ExampleConsumer>(context);
ec.EnablePriority(5);
ec.UseRetry(retryConfig =>
{
// exponential backup in minutes
retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
retryConfig.Handle<HttpRequestException>(x => x.IsTransient());
retryConfig.Handle<SocketException>(x => x.IsTransient());
});
ec.UseRetry(retryConfig =>
{
// exponential backup in seconds
retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
retryConfig.Handle<DatabaseException>(x => x.IsTransient());
retryConfig.Handle<SqlException>(x => x.IsTransient());
});
});
В настоящее время используется только вторая. Похоже, что первая из них перезаписана.
Я также пытался настроить повторные попытки второго уровня следующим образом:
cfg.ReceiveEndpoint(
host,
"QueueName",
ec =>
{
ec.Consumer<ExampleConsumer>(context, factory =>
{
factory.UseRetry(retryConfig =>
{
// exponential backup in seconds for sql and concurrency exceptions
retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
retryConfig.Handle<DatabaseException>(x => x.IsTransient());
retryConfig.Handle<SqlException>(x => x.IsTransient());
});
});
ec.EnablePriority(5);
ec.UseRetry(retryConfig =>
{
// exponential backup in minutes for http request exceptions
retryConfig.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
retryConfig.Handle<DatabaseException>(x => x.IsTransient());
retryConfig.Handle<SqlException>(x => x.IsTransient());
});
});
Но, похоже, это тоже не работает. Кто-нибудь знает, как я могу применять разные интервалы повторных попыток для разных типов исключений?
Ответ №1:
MassTransit создает все как конвейер, и порядок фильтров имеет значение. Переписывание вашего примера выше должно устранить проблему (все, что я сделал, это переместил пользователя в конец).
cfg.ReceiveEndpoint("ExampleQueueName", ec =>
{
ec.EnablePriority(5);
ec.UseMessageRetry(r =>
{
r.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
r.Handle<HttpRequestException>(x => x.IsTransient());
r.Handle<SocketException>(x => x.IsTransient());
});
ec.UseMessageRetry(r =>
{
r.Intervals(new[] { 1, 2, 4, 8, 16, 32 }.Select(t => TimeSpan.FromSeconds(t)).ToArray());
r.Handle<DatabaseException>(x => x.IsTransient());
r.Handle<SqlException>(x => x.IsTransient());
});
ec.Consumer<ExampleConsumer>(context);
});