C#Masstransit如何在队列不可用或关闭时处理异常

时间:2016-09-15 10:14:59

标签: c#-4.0 rabbitmq masstransit

我正在使用Masstransit与RabbitMQ来消耗来自队列的消息。任何人都可以告诉我如何在队列关闭或无法获取消息时处理异常?以下是我的设置:

    var busControl = Bus.Factory.CreateUsingRabbitMq(cfg =>
    {
        var host = cfg.Host(new Uri(configManager.RabbitMqUrl), h =>
        {
            h.Username(configManager.RabbitMqUserName);
            h.Password(configManager.RabbitMqPassword);
        });

        cfg.ReceiveEndpoint(host, RabbitMqConstants.Change, e =>
        {
            e.UseRetry(Retry.Immediate(configManager.ProcessorRetryNumber));
            e.Handler<ChangeDetected>(context =>
            {
                var task = Task.Run(() => consumer.Consume(context));
                return task;
            });
        });
    });

由于

3 个答案:

答案 0 :(得分:3)

在我们内部的RabbitMQ消息传递实现中,我们以两种方式接近/解决了这个(发布时不可用)的发布方面:

[1]我们使用Polly来异步编排有限数量的发布重试(尝试之间有延迟)。这克服了与代理的连接丢失是次要网络昙花一现的情况。

[2]如果所有发布的重试都失败了,我们会使用“&#39;”医院&#39;概念:我们将关于失败发布消息的足够详细信息存储到备用源(数据库;附加故障转移到本地文件存储),以便我们可以在以后重新发布失败的消息(如果需要)。存储和转发的变体&#39; (我们可以批量重新发布,但我们也允许手动干预以选择是否重新发布)。

所有这一切都取决于它对您的重要性,永远不会丢失信息&#39;。 RabbitMQ经纪人的一些冗余(克里斯帕特森建议或联合集群)也是一个明显的步骤。如果您丢失/想要对您的一个/某些经纪人进行维护,则群集/联合可为您提供保护。上面的弹性策略[1],[2]为您提供保护,如果由于某种原因,消息发布者无法看到任何 RabbitMQ代理(例如,发布者附近的网络故障)。

答案 1 :(得分:2)

对于接收消息,MassTransit将在重新联机时自动重新连接到代理(RabbitMQ)。对于发送消息,如果您的应用程序无法连接到要发送的代理,则完全是另一个问题。

在应用程序中使用消息传递时,它通常会成为基础架构中最重要的一个方面。因此,如果您需要高可用性,那么您的未来可能会进行集群设置(有关于将RabbitMQ集群化的文章)。

MassTransit中没有任何存储转发概念,代理需要可用。虽然已经讨论了一些选项,但目前没有什么是具体的,也没有普遍适用的。

答案 2 :(得分:0)

在阅读其文档后,我意识到 MassTransit 只是不处理生产者未能发送/发布到 MQ 或消费者未能发回 ACK 的情况。

所以我必须使用另一个工具 CAP,它实现了一个本地事务表。您可以将发送消息操作放在业务代码的同一个本地数据库事务中。但缺点是 CAP 还没有实现 saga。

否则,您必须自己使用本地事务表实现持久发件箱模式。