编程语言
首页 > 编程语言> > c#-使用EasyNetQ发布消息并且断开总线时会发生什么?

c#-使用EasyNetQ发布消息并且断开总线时会发生什么?

作者:互联网

我目前正在对此进行调查,但以为我还是会问.一旦找到答案,将发布答案.

问题如下:

应用程序调用RabbitHutch.CreateBus来创建IBus / IAdvancedBus实例,以将消息发布到RabbitMQ.返回实例,但IsConnected标志设置为false(即连接重试在后台完成).当应用程序服务于特定请求时,在仍未连接总线的情况下,将调用IAdvancedBus.PublishAsync来发布消息.在很大的负载下,由于总线无法连接到RabbitMQ,因此对应用程序的请求最终超时.

当处理请求时失去与RabbitMQ的连接时,会观察到相同的行为.

问题是:

总线断开时,EasyNetQ如何处理试图发布消息的尝试?

消息是否会在内存中排队直到可以建立连接?如果是这样,达到一定限制后是否处理邮件?这是可配置的吗?

还是迫使总线尝试连接到RabbitMQ?

还是完全转储邮件?

PublisherConfirm是否已打开以影响行为?

解决方法:

我尚未能够测试上述所有场景,但是看起来在尝试发布到RabbitMQ之前,EasyNetQ正在检查总线是否已连接.如果不是,则它或多或少进入连接循环,如下所述:https://github.com/EasyNetQ/EasyNetQ/wiki/Error-Conditions#there-is-a-network-failure-between-my-subscriber-and-the-rabbitmq-broker

随着负载的增加,连接循环似乎失去了控制,因为我们的基础架构或配置已损坏,因此它们都无法连接到RabbitMQ.为什么会出现我尚未确定的超时,但是我怀疑当多个连接循环尝试同时连接时可能会出现并发问题.

我也怀疑关闭PublisherConfirm确实会有所帮助,因为我们无法发布消息,因此不等待RabbitMQ的确认.

我们的解决方案:

那么,为什么我对这个问题没有一个明确的答案?事实是,严格来说,在这个时间点上,我们尝试发布的消息不是关键任务.如果我们的配置错误,则在运行状况检查时部署将失败,并且我们实质上将中止部署.如果RabbitMQ由于某种原因变得不可用,我们可以不发布这些消息.

另外,为避免超时,我们在检测到应用程序和RabbitMQ之间的电路断开时,用断路器将消息发布包装起来以停止消息发布.粗略地说,它的工作方式如下:

var bus = RabbitHutch.Create(...).Advanced;
var rabbitMqCircuitBreaker = new CircuitBreaker(...);
rabbitMqCircuitBreaker.AttemptCall(() => {
    if (!bus.IsConnected)
       throw new Exception(...);
    bus.Publish(...);
});

请注意,我们通过抛出异常将IsConnected标志设置为false时通知断路器.如果在配置的时间内抛出X次异常,则电路将断开,我们将停止尝试在配置的时间内发布消息.我们认为这是可以接受的,因为如果RabbitMQ可用,那么连接应该真的可以快速并且有99.xxx%的时间可用.同样值得注意的是,总线是在我们的应用程序启动时创建的,而不是在每次调用之前创建的,因此在有效场景中实际设置该标志之前检查标志的可能性非常低.

目前为我们工作,任何其他信息将不胜感激.

标签:rabbitmq,easynetq,c
来源: https://codeday.me/bug/20191120/2045543.html