RabbitMQ.Client.TopologyRecoveryException问题与解决

封装了一下RabbitMQ驱动的调用,扔给团队用,一直也没出现啥问题,
昨天同事突然反馈给我,说调试时一直报错:

Topology recovery exception: RabbitMQ.Client.TopologyRecoveryException: Caught an exception while recovering exchange xxxxx: Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Application, code=200, text="Goodbye", classId=0, methodId=0, cause= ---> RabbitMQ.Client.Exceptions.AlreadyClosedException: Already closed: The AMQP operation was interrupted: AMQP close-reason, initiated by Application, code=200, text="Goodbye", classId=0, methodId=0, cause=
   在 RabbitMQ.Client.Impl.SessionBase.Transmit(Command cmd)
   在 RabbitMQ.Client.Impl.ModelBase.ModelRpc(MethodBase method, ContentHeaderBase header, Byte[] body)
   在 RabbitMQ.Client.Framing.Impl.Model._Private_ExchangeDeclare(String exchange, String type, Boolean passive, Boolean durable, Boolean autoDelete, Boolean internal, Boolean nowait, IDictionary`2 arguments)
   在 RabbitMQ.Client.Impl.ModelBase.ExchangeDeclare(String exchange, String type, Boolean durable, Boolean autoDelete, IDictionary`2 arguments)
   在 RabbitMQ.Client.Impl.RecordedExchange.Recover()
   在 RabbitMQ.Client.Framing.Impl.AutorecoveringConnection.RecoverExchanges()

过去他的机器一看,在调试过程中,不定时抛出上面的错误,而同样的程序,线上运行好好的,根本不报错。
错误也说是正常断开,GoodBye……

找了半天资料,没发现什么特别的地方,自己测试发现等一定时间后也会出这个错误。
创建连接的代码如下:

{
    HostName = "127.0.0.1",
    Port = 5672,
    UserName = "admin",
    Password = "123456",
    //Socket read timeout is twice the hearbeat
    RequestedHeartbeat = 1000,
    AutomaticRecoveryEnabled = true,
};
var connection = connectionFactory.CreateConnection("exchangeName");
return connection;

后面另一个同事看了下,说心跳为啥设置那么短???
一语惊醒,正常代码运行中,心跳机制不会卡住,所以也就不会出错,
而如果在调试过程中,加入了断点,一个断点等几秒是很正常的,自然也会卡住心跳机制的正常运作。
参考官方说明:
https://www.rabbitmq.com/heartbeats.html
简要翻译下,RabbitMQ的默认心跳时长为60秒,每半个周期(30秒)会发一次心跳包,如果丢失2个心跳包,就会认为连接断了,需要重新连接。
根据历年用户的反馈意见,这个值如果低于5秒,会导致误报,1秒以下几乎都会导致误报,比较合适的值是5~20秒。
设置为0可以禁用心跳机制。

注:设置了RequestedHeartbeat,会同时开启服务端和客户端的心跳机制,在指定时间内:
1、服务端在无数据发送的情况下,会发心跳包给客户端;或者没收到客户端数据,会认为心跳超时;
2、客户端也会触发发送和接收心跳包的Timer机制,判断发送和接收超时情况

猜你喜欢

转载自blog.csdn.net/youbl/article/details/79024061