.net/c# RabbitMQ 连接断开处理-断线重连(转载)
Rabbitmq 官方给的NET consumer示例代码如下,但使用过程,会遇到connection断开的问题,一旦断开,这个代码就会报错,就会导致消费者或者生产者挂掉。
下图是生产者发送消息,我手动停止了rabbitmq,然后又重新启动了rabbitmq,大概等启动成功以后,为了防止服务没有完全启动,我又等待了10秒钟
服务完全启动成功以后,我尝试重新发送一些消息,报错,如下:
************** 异常文本 **************
RabbitMQ.Client.Exceptions.AlreadyClosedException: Already closed: The
AMQP operation was interrupted: AMQP close-reason, initiated by Peer,
code=320, text="CONNECTION_FORCED - broker forced connection closure
with reason 'shutdown'", classId=0, methodId=0, cause=
在 RabbitMQ.Client.Impl.SessionBase.Transmit(Command cmd)
在 RabbitMQ.Client.Impl.ModelBase.ModelSend(MethodBase method, ContentHeaderBase header, Byte[] body)
在 RabbitMQ.Client.Impl.ModelBase.BasicPublish(String exchange, String
routingKey, Boolean mandatory, IBasicProperties basicProperties, Byte[]
body)
在 RabbitMQ.Client.Impl.ModelBase.BasicPublish(String exchange, String
routingKey, IBasicProperties basicProperties, Byte[] body)
在 rabbitMQ_Publish.Form1.button1_Click(Object sender, EventArgs e) 位置
C:\project\my\RabbitMQ-demo\rabbitMQ-Publish\Form1.cs:行号 37
在 System.Windows.Forms.Control.OnClick(EventArgs e)
在 System.Windows.Forms.Button.OnClick(EventArgs e)
在 System.Windows.Forms.Button.PerformClick()
在 System.Windows.Forms.Form.ProcessDialogKey(Keys keyData)
在 System.Windows.Forms.TextBoxBase.ProcessDialogKey(Keys keyData)
在 System.Windows.Forms.Control.PreProcessMessage(Message& msg)
在 System.Windows.Forms.Control.PreProcessControlMessageInternal(Control target, Message& msg)
在 System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)

那么如何会异常恢复呢?或者说断线重连呢?
RabbitMQ NET Client的源码,研究发现一种自动的错误恢复机制 AutomaticRecoveryEnabled = true 使用方式如下
- var factory = new ConnectionFactory() { HostName = "localhost", AutomaticRecoveryEnabled = true };
复制代码
具体的恢复机制如下
1.在AutoRecoveringConnection初始化时,在链接关闭事件委托上增加断开处理
- public void init()
- {
- m_delegate = new Connection(m_factory, false, m_factory.CreateFrameHandler());
- AutorecoveringConnection self = this;
- EventHandler<ShutdownEventArgs> recoveryListener = (_, args) =>
- {
- lock (recoveryLockTarget)
- {
- if (ShouldTriggerConnectionRecovery(args))
- {
- try
- {
- self.BeginAutomaticRecovery();
- }
- catch (Exception e)
- {
- // TODO: logging
- Console.WriteLine("BeginAutomaticRecovery() failed: {0}", e);
- }
- }
- }
- };
- lock (m_eventLock)
- {
- ConnectionShutdown += recoveryListener;
- if (!m_recordedShutdownEventHandlers.Contains(recoveryListener))
- {
- m_recordedShutdownEventHandlers.Add(recoveryListener);
- }
- }
- }
复制代码
观察调用的方式BeginAutomaticRecovery,可以看到这个方法内部调用了PerformAutomaticRecovery方法。我们直接看这个方法的内容,其中第一个调用的是方法RecoverConnectionDelegate
- protected void PerformAutomaticRecovery()
- {
- lock (recoveryLockTarget)
- {
- RecoverConnectionDelegate();
- RecoverConnectionShutdownHandlers();
- RecoverConnectionBlockedHandlers();
- RecoverConnectionUnblockedHandlers();
- RecoverModels();
- if (m_factory.TopologyRecoveryEnabled)
- {
- RecoverEntities();
- RecoverConsumers();
- }
- RunRecoveryEventHandlers();
- }
- }
复制代码
这个方法中调用的是
- protected void RecoverConnectionDelegate()
- {
- bool recovering = true;
- while (recovering)
- {
- try
- {
- m_delegate = new Connection(m_factory, false, m_factory.CreateFrameHandler());
- recovering = false;
- }
- catch (Exception)
- {
- // TODO: exponential back-off
- Thread.Sleep(m_factory.NetworkRecoveryInterval);
- // TODO: provide a way to handle these exceptions
- }
- }
- }
复制代码
可以看出,它是执行了死循环,直到连接重新打开,当然,如果遇到异常,它会调用Thread.Sleep来等待一下,然后再次执行连接恢复。
转载自: https://www.itsvse.com/thread-4636-1-1.html
.net/c# RabbitMQ 连接断开处理-断线重连(转载)的更多相关文章
- RabbitMQ---8、连接断开处理-断线重连
本文转载于:https://www.itsvse.com/thread-4636-1-1.html: 参考文献:http://www.likecs.com/show-29874.html:https: ...
- nodejs使用MYSQL连接池,断线重连
两种方式解决1.你可以配置mysql的连接池 var mysql = require('mysql'); var pool = mysql.createPool({ host: 'localhost' ...
- socket 如何判断远端服务器的连接状态?连接断开,需重连
fluent-logger-java is a Java library, to record events via Fluentd, from Java application. https://g ...
- RabbitMQ 连接断开处理-自动恢复
Rabbitmq 官方给的NET consumer示例代码如下,但使用过程,会遇到connection断开的问题,一旦断开,这个代码就会报错,如果你的消费者端是这样的代码的话,就会导致消费者挂掉. u ...
- Spring-Data-Redis 下实现jedis连接断开后自动重连
原先使用jedis的时候,处理手段是在从连接池获取连接时捕获JedisConnectionException异常,在异常处理部分重新获取连接,但是spring data redis似乎不会,如下所示: ...
- RabbitMQ连接池、生产者、消费者实例
1.本文分享RabbitMQ的工具类,经过实际项目长期测试,在此分享给发家,各位大神有什么建议请指正 !!! 2.下面是链接池主要代码: import java.util.HashMap; impor ...
- 我为什么要选择RabbitMQ ,RabbitMQ简介,各种MQ选型对比(转载)
转载自:https://www.sojson.com/blog/48.html 前言: MQ 是什么?队列是什么,MQ 我们可以理解为消息队列,队列我们可以理解为管道.以管道的方式做消息传递. 场景: ...
- Netty(六):Netty中的连接管理(心跳机制和定时断线重连)
何为心跳 顾名思义, 所谓心跳, 即在TCP长连接中, 客户端和服务器之间定期发送的一种特殊的数据包, 通知对方自己还在线, 以确保 TCP 连接的有效性. 为什么需要心跳 因为网络的不可靠性, 有可 ...
- 【问题记录】—SignalR连接断线重连
起因: ASP.NET Core SignalR是一个开源库,可简化向应用添加实时 SignalR Web 功能. 实时 Web 功能使服务器端代码能够立即将内容推送到客户端.(相信大家都用得比较多了 ...
随机推荐
- VUE router-view 页面布局 (嵌套路由+命名视图)
嵌套路由 实际生活中的应用界面,通常由多层嵌套的组件组合而成.同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如: /user/foo/profile /user/foo/posts ...
- Linux 挂载和卸载U盘
一般的U盘挂载方法: mount [-fnrsvw] [-t vfstype] [-o options] device dir 参数:device表示要挂载的设备,dir表示挂载点 -t 指定设备的 ...
- angular之interceptors拦截器
<!DOCTYPE html> <html ng-app="nickApp"> <head> <meta charset="UT ...
- scala 学习笔记八 简洁性
Scala可以简洁地表示概念,有时甚至可以说过于简洁. 1.消除中间结果 在组合表达式中,最后一个表达式会变成整个表达式的结果.下面的例子中,值会被捕获到val result中,然后result从方法 ...
- 使用ViewDragHelper打造属于自己的DragLayout(抽屉开关 )
使用ViewDragHelper打造属于自己的DragLayout(抽屉开关 ) DrawLayout这个自己定义的空间非经常见.qq,网易新闻.知乎等等,都有这样的效果,那这样的效果是如何实现的呢? ...
- Design Your Own Protocol In Five Minutes
https://mayaposch.wordpress.com/2011/10/03/design-your-own-protocol-in-five-minutes ---------------- ...
- Cognos定时Email发送报表数据功能
1:进入 IBM Cognos Configuration-Data Access-Notification 2:设置如下(注意一定要是smtp服务,端口25,我这里是用了腾讯邮箱的smtp服务) 当 ...
- easyui combobox实现本地模糊查询
直接上代码 $("#combobox1").combobox({ valueField : "value", textField : "text&qu ...
- Memcache and Mongodb
转自:http://www.cnblogs.com/lovecindywang/archive/2010/05/19/1739025.html 先说说自己对Memcache和Mongodb的一些看法. ...
- 使用Fiddler抓包调试https下的页面
众所周知https技术诞生以来,一个很重要的作用就是加密通信内容.所以在项目团队将业务站点实施完https改造以后,原先使用fiddler进行抓包的美好生活到头了.其实fiddler本身是支持对于ht ...