如何在MassTransit中配置多个重试策略

时间:2019-03-14 09:57:48

标签: rabbitmq masstransit

我想要针对特定​​使用者的两个单独的重试策略。一个用于HttpRequestExceptionSocketException,另一个用于自定义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 个答案:

答案 0 :(得分:0)

MassTransit将所有内容构建为管道,并且过滤器的顺序很重要。在上面重写您的示例应该可以解决该问题(我所做的只是将Consumer移至末尾)。

cfg.ReceiveEndpoint(
host,
"ExampleQueueName",
ec =>
{
    ec.EnablePriority(5);
    ec.UseRetry(retryConfig =>
    {
        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 =>
    {
        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.Consumer<ExampleConsumer>(context);
});