我无法测试上述所有场景,但看起来在尝试发布到 RabbitMQ 之前,EasyNetQ 正在检查总线是否已连接。如果不是,它或多或少地进入了一个连接循环,如下所述:https ://github.com/EasyNetQ/EasyNetQ/wiki/Error-Conditions#there-is-a-network-failure-between-my -subscriber-and-the-rabbitmq-broker
随着我们负载的增加,看起来连接循环正在失控,因为我们的基础设施或配置已损坏,它们都无法连接到 RabbitMQ。为什么我们会出现我尚未确定的超时,但我怀疑当多个连接循环尝试同时连接时可能会出现并发问题。
我也怀疑关闭 PublisherConfirms 是否会有所帮助,因为我们无法发布消息,因此无需等待 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% 的时间可用。另外值得注意的是,总线是在我们的应用程序启动时创建的,而不是在每次调用之前创建的,因此在有效场景中实际设置之前检查标志的可能性非常低。
目前为我们工作,任何其他信息将不胜感激。